Spring Security认证器实现过程详解
什么是Spring Security认证器
Spring Security是一个基于安全框架的安全性认证和授权框架,也是Spring框架中的一个子项目。它负责管理我们应用程序中的用户、角色和权限,并为它们提供安全访问。
Spring Security身份认证的实现过程主要涉及到AuthenticationManager、UserDetailsService和PasswordEncoder这些核心概念。
AuthenticationManager是身份认证的核心,它有一个authenticate方法,用来验证用户的身份。UserDetailsService是用来获取用户详细信息的接口,而PasswordEncoder用来加密用户的密码。
Spring Security认证器实现过程
步骤一:引入Spring Security
在pom.xml文件中,添加Spring Security的依赖。
<dependencies>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>5.4.2</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>5.4.2</version>
</dependency>
</dependencies>
步骤二:配置Spring Security
在项目中添加一个名为security的XML配置文件,并添加以下内容:
<security:http auto-config="true" use-expressions="true">
<security:intercept-url pattern="/admin/**" access="hasRole('ROLE_ADMIN')" />
<security:intercept-url pattern="/user/**" access="hasAnyRole('ROLE_USER', 'ROLE_ADMIN')" />
<security:form-login login-page="/login" default-target-url="/home" authentication-failure-url="/login?error=true" />
<security:logout logout-success-url="/login" />
</security:http>
<security:authentication-manager>
<security:authentication-provider>
<security:user-service>
<security:user name="admin" password="{noop}admin123" authorities="ROLE_ADMIN" />
<security:user name="user" password="{noop}user123" authorities="ROLE_USER" />
</security:user-service>
</security:authentication-provider>
</security:authentication-manager>
上述配置文件将会以下内容:
- 配置了HTTP的安全性,具有自动配置和表达式。
- 配置了拦截器URL,只有admin用户才能访问/admin/,而有“ROLE_USER”或“ROLE_ADMIN”权限的用户可以访问/user/。
- 配置了表单登录,登录页面为/login,登录失败的话,会跳转到/login?error=true。
- 配置退出登录,退出成功之后跳转到/login,同时删除Session。
其中,authentication-provider会在Spring Security中管理用户的验证和角色。在这个例子中,我们简单地将用户集成到XML文件中,方便测试。
步骤三:测试
我们创建一个测试controller,在前面的配置中,这个控制器只有Admin角色可以访问。
@RestController
@RequestMapping("/admin")
public class AdminController {
@GetMapping("/")
public String adminHome() {
return "Hello, admin!";
}
}
此时运行程序,访问url为localhost:8080/admin 将会跳转到登录页面,用户名为admin,密码为admin123登录就可以访问/admin了。如果用user登录,就只能访问/user了。
示例
示例一:基于数据库的认证器
在实际项目中,我们往往不会将用户信息直接保存到XML文件中,更常用的方式是保存在数据库中。我们可以通过自定义UserDetailsService重写loadUserByUsername方法从数据库中读取用户数据。
@Service("userDetailsService")
public class UserDetailsServiceImpl implements UserDetailsService {
@Autowired
private UserDao userDao;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userDao.getUserByUsername(username);
if (user == null) {
throw new UsernameNotFoundException(username);
}
return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(),
getAuthorities(user.getRoles()));
}
private static List<GrantedAuthority> getAuthorities(List<String> roles) {
List<GrantedAuthority> authorities = new ArrayList<>();
for (String role : roles) {
authorities.add(new SimpleGrantedAuthority(role));
}
return authorities;
}
}
示例二:自定义用户认证器
有时候,我们没有必要将用户信息存储到数据库中,而是希望能够在代码中进行认证。这时候,我们就需要使用自定义的用户认证器。
@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
String name = authentication.getName();
String password = authentication.getCredentials().toString();
if ("admin".equals(name) && "admin123".equals(password)) {
List<GrantedAuthority> grantedAuths = new ArrayList<>();
grantedAuths.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
Authentication auth = new UsernamePasswordAuthenticationToken(name, password, grantedAuths);
return auth;
} else {
return null;
}
}
@Override
public boolean supports(Class<?> authentication) {
return authentication.equals(UsernamePasswordAuthenticationToken.class);
}
}
在上面的示例中,我们自定义了一个认证器,在authenticate方法中,我们定义了一个虚拟用户admin,密码为admin123,只有当用户输入的用户名和密码与之匹配时,认证才会成功。而在supports方法中,我们返回的是一个UsernamePasswordAuthenticationToken类型,这意味着我们需要使用它来认证用户。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring Security认证器实现过程详解 - Python技术站