UsernamePasswordAuthenticationToken的作用及其介绍
时间: 2023-06-07 17:10:41 浏览: 351
UsernamePasswordAuthenticationToken 是 Spring Security 框架中的一种身份验证令牌,用于基于用户名和密码进行身份验证。它包含一个用户名和一个密码,还可以包含其他细节信息,如 IP 地址和请求详细信息等。当用户进行身份验证时,将使用该信息来验证其身份,并决定是否授予对资源的访问权限。UsernamePasswordAuthenticationToken 是 Authentication 接口的实现类,因此可以将其传递给其他 Spring Security 方法进行身份验证和授权。
相关问题
UsernamePasswordAuthenticationToken 返回 Not granted any authorities
`UsernamePasswordAuthenticationToken` 是 Spring Security 中的一个重要类,它用于封装用户登录时提供的用户名和密码信息,并可能包含权限信息。当一个 `UsernamePasswordAuthenticationToken` 对象被验证后,如果认证失败或者该用户没有被授予任何权限(即没有任何`GrantedAuthority`),Spring Security 就会抛出 `AccessDeniedException`,其中包含一条消息 "Not granted any authorities"。
这条消息表明系统检查了用户的身份及其关联的权限,但用户没有获得任何有效的权限,因此无法进行后续的操作,如访问某个受保护的资源或执行某些操作。
使用spring security,对数据库中的admin表(id,name,pwd,没有别的字段),student表(id,name,pwd,没有别的字段)的账户密码进行相应的角色配置,并使用oauth2做登录校验,拦截相应url做角色鉴权,及其登录时的处理步骤(假设checkLogin(name,pwd)方法已经定义好),给出代码
好的,以下是对您所描述的场景进行实现的示例代码:
1. 引入依赖
```xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth.boot</groupId>
<artifactId>spring-security-oauth2-autoconfigure</artifactId>
<version>2.1.0.RELEASE</version>
</dependency>
```
2. 配置application.yml
```yaml
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/testdb?useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: root
security:
oauth2:
client:
client-id: client
client-secret: secret
authorized-grant-types: password,authorization_code,refresh_token
scopes: all
resource:
jwt:
key-value: test
```
3. 配置SecurityConfig
```java
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private DataSource dataSource;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/oauth/**").permitAll()
.antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/student/**").hasRole("STUDENT")
.anyRequest().authenticated()
.and().formLogin();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication().dataSource(dataSource)
.usersByUsernameQuery("select name,pwd,1 from admin where name=?")
.authoritiesByUsernameQuery("select name,'ROLE_ADMIN' from admin where name=?")
.passwordEncoder(new BCryptPasswordEncoder());
auth.jdbcAuthentication().dataSource(dataSource)
.usersByUsernameQuery("select name,pwd,1 from student where name=?")
.authoritiesByUsernameQuery("select name,'ROLE_STUDENT' from student where name=?")
.passwordEncoder(new BCryptPasswordEncoder());
}
}
```
4. 配置OAuth2
```java
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private DataSource dataSource;
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.jdbc(dataSource);
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authenticationManager);
}
@Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer.tokenKeyAccess("permitAll()")
.checkTokenAccess("isAuthenticated()")
.allowFormAuthenticationForClients();
}
}
```
5. 配置Controller
```java
@RestController
@RequestMapping("/api")
public class ApiController {
@GetMapping("/admin")
public String admin() {
return "Hello, Admin!";
}
@GetMapping("/student")
public String student() {
return "Hello, Student!";
}
}
```
6. 编写登录接口
```java
@RestController
@RequestMapping("/oauth")
public class LoginController {
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private TokenStore tokenStore;
@PostMapping("/login")
public String login(@RequestParam String name, @RequestParam String pwd) {
Authentication authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(name, pwd));
SecurityContextHolder.getContext().setAuthentication(authentication);
return JSON.toJSONString(tokenStore.getAccessToken(authentication));
}
@GetMapping("/logout")
public String logout(HttpServletRequest request) {
String authHeader = request.getHeader("Authorization");
if (authHeader != null) {
String tokenValue = authHeader.replace("Bearer", "").trim();
OAuth2AccessToken accessToken = tokenStore.readAccessToken(tokenValue);
tokenStore.removeAccessToken(accessToken);
}
return "Logout success!";
}
}
```
上述代码中,我们使用了BCryptPasswordEncoder对密码进行加密,并配置了两个角色ADMIN和STUDENT,对不同角色的API进行了鉴权。在登录时,我们使用了AuthenticationManager对用户进行认证,并使用TokenStore存储Token,供后续API访问时进行鉴权。在退出登录时,我们需要调用OAuth2的注销接口,使Token失效。
以上就是一个简单的使用spring security和oauth2对数据库中的账户密码进行角色配置和登录校验的示例代码。
阅读全文