黑马程序员技术交流社区
标题: 【广州校区】+【原创】+SpringSecurity自定义权限认证 [打印本页]
作者: hydee 时间: 2018-5-23 18:47
标题: 【广州校区】+【原创】+SpringSecurity自定义权限认证
本帖最后由 hydee 于 2018-5-23 19:00 编辑
1.Spring Security的认证规则
要编写自定义的认证规则,首先需要对Spring Security中的认证规则有一定的了解,下面简单介绍下Spring Security的认证规则。
1)在Spring Security中每个URL都是一个资源,当系统启动的时候,Spring Security会根据配置将所有的URL与访问这个URL所需要的权限的映射数据加载到Spring Security中。
2)当一个请求访问一个资源时,Spring Security会判断这个URL是否需要权限验证,如果不需要,那么直接访问即可。
3)如果这个URL需要进行权限验证,那么Spring Security会检查当前请求来源所属用户是否登录,如果没有登录,则跳转到登录页面,进行登录操作,并加载这个用户的相关信息
4)如果登录,那么判断这个用户所拥有的权限是否包含访问这个URL所需要的权限,如果有则允许访问,否则不予放行。
2.自定义认证和权限判断实现
2.1自定义UserDetailsService
@Component
public class CustomUserDetailsService implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
LogManager.getLogger("CustomUserDetailsService").info("loadUserByUsername invoke");
// 提供到数据库查询该用户的权限信息
// 关于角色和权限的转换关系在此处处理,根据用户与角色的关系、角色与权限的关系,
// 此处伪造一些数据
// 伪造权限
AuthorityModel authority = new AuthorityModel("AUTH_WELCOME");
List<AuthorityModel> authorities = new ArrayList<>();
authorities.add(authority);
AccountInfoModel account = new AccountInfoModel("oolong", "12345");
account.setAuthorities(authorities);
return account;
}
}
2.2自定义AuthenticationProvider
@Componentpublic class CustomUserDetailsAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider {
@Autowired
private UserDetailsService userDetailsService;
public UserDetailsService getUserDetailService() {
return this.userDetailsService;
}
public void setUserDetailService(UserDetailsService userDetailsService) {
this.userDetailsService = userDetailsService;
}
@Override
protected void additionalAuthenticationChecks(UserDetails userDetails,
UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
}
@Override
protected UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken authentication)
throws AuthenticationException {
LogManager.getLogger("CustomUserDetailsAuthenticationProvider").info("retrieveUser invoke");
if (userDetailsService == null) {
throw new AuthenticationServiceException("");
}
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
if (userDetails == null) {
throw new UsernameNotFoundException(username);
}
if (userDetails.getUsername().equals(authentication.getPrincipal().toString())
&& userDetails.getPassword().equals(authentication.getCredentials().toString())) {
return userDetails;
}
throw new BadCredentialsException(username + authentication.getCredentials());
}
}
2.4自定义AccessDecisionManager
@Componentpublic class CustomAccessDecisionManager implements AccessDecisionManager {
@Override
public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes)
throws AccessDeniedException, InsufficientAuthenticationException {
LogManager.getLogger("CustomAccessDecisionManager").info("decide invoke");
if (configAttributes == null) {
return;
}
if (configAttributes.size() <= 0) {
return;
}
Iterator<ConfigAttribute> authorities = configAttributes.iterator();
String needAuthority = null;
while(authorities.hasNext()) {
ConfigAttribute authority = authorities.next();
if (authority == null || (needAuthority = authority.getAttribute()) == null) {
continue;
}
LogManager.getLogger("CustomAccessDecisionManager").info("decide == " + needAuthority);
for (GrantedAuthority ga : authentication.getAuthorities()) {
if (needAuthority.equals(ga.getAuthority().trim())) {
return;
}
}
}
throw new AccessDeniedException("No Authority");
}
@Override
public boolean supports(ConfigAttribute attribute) {
return true;
}
@Override
public boolean supports(Class<?> clazz) {
return true;
}
}
3.实现组合配置
在Spring MVC中,Spring Security是通过过滤器发挥作用的,因此我们就爱那个决策管理器与数据加载放到一个过滤器中,然后将这个过滤器插入到系统的过滤器链中。
@Configuration
@ComponentScan(basePackageClasses={TempHook.class})
@EnableWebSecuritypublic class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private CustomUserDetailsAuthenticationProvider customAuthenticationProvider;
@Autowired
private CustomAccessDecisionManager customAccessDecisionManager;
@Autowired
private CustomSecurityMetadataSource customSecurityMetadataSource;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(customAuthenticationProvider);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.addFilterAfter(customFilterSecurityInterceptor(), ExceptionTranslationFilter.class);
http.formLogin();
}
@Bean
public FilterSecurityInterceptor customFilterSecurityInterceptor() {
FilterSecurityInterceptor fsi = new FilterSecurityInterceptor();
fsi.setAccessDecisionManager(customAccessDecisionManager);
fsi.setSecurityMetadataSource(customSecurityMetadataSource);
return fsi;
}
}
-
01_Security结构图.png
(19.9 KB, 下载次数: 9)
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) |
黑马程序员IT技术论坛 X3.2 |