spring security使用和原理简析
Posted jiataoq
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring security使用和原理简析相关的知识,希望对你有一定的参考价值。
主要参考:https://blog.csdn.net/u012373815/article/details/55225079
源码参考:https://github.com/527515025/springBoot
项目需求
1:实现了用户、角色、权限的动态管理,可以管控到接口地址,已经访问方式(get,post)
2:自定义登录接口
3:结合spring-session,来保存用户登录信息
表结构说明
method来控制相同方法名的不同访问方式(get,post,put等)
项目结构
废话不多说,看一下实现功能的核心代码
SecurityConfig核心方法
protected void configure(HttpSecurity http) throws Exception http.csrf().disable() //访问未授权资源的异常,403 .exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and() //登录后访问未配置权限资源的异常,401 .exceptionHandling().accessDeniedHandler(accessDeniedHandler).and() .authorizeRequests() //匿名用户也可以访问的资源 .antMatchers("/api/v1/auth").permitAll() .antMatchers("/logout").permitAll() .antMatchers("/**","/swagger-resources/**","/translate_a/**","/doc.html", "/webjars/**", "/v2/**", "/META-INF/resources/webjars/","/META-INF/resources/").permitAll() .anyRequest().authenticated() .and() //开启session,同时只能登录一个用户 .sessionManagement().maximumSessions(1).sessionRegistry(sessionRegistry) .and() .and() .logout().logoutUrl("/api/v1/logout") .invalidateHttpSession(true) .clearAuthentication(true) .and() .httpBasic();
UrlFilterSecurityInterceptor核心方法
@Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException FilterInvocation fi = new FilterInvocation(request, response, chain); invoke(fi); public void invoke(FilterInvocation fi) throws IOException, ServletException //fi里面有一个被拦截的url //里面调用MyInvocationSecurityMetadataSource的getAttributes(Object object)这个方法获取fi对应的所有权限 //再调用MyAccessDecisionManager的decide方法来校验用户的权限是否足够 InterceptorStatusToken token = super.beforeInvocation(fi); try //执行下一个拦截器 fi.getChain().doFilter(fi.getRequest(), fi.getResponse()); finally super.afterInvocation(token, null);
UrlAccessDecisionManager核心方法
public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException HttpServletRequest request = ((FilterInvocation) object).getHttpRequest(); String url, method; //关闭鉴权 if (true) return; //放行在config中配置的无需登录就能访问的资源 if ( matchers("/api/v1/auth", request) || matchers("/swagger-resources/**", request) || matchers("/translate_a/**", request) || matchers("/doc.html", request) || matchers("/webjars/**", request) || matchers("/v2/**", request) || matchers("/META-INF/resources/webjars/**", request) || matchers("/META-INF/resources/**", request)) return; else //匹配用户所具有的接口访问权限 for (GrantedAuthority ga : authentication.getAuthorities()) if (ga instanceof UrlGrantedAuthority) UrlGrantedAuthority urlGrantedAuthority = (UrlGrantedAuthority) ga; url = urlGrantedAuthority.getPermissionUrl(); method = urlGrantedAuthority.getMethod(); if (matchers(url, request)) if (method.equals(request.getMethod()) || "ALL".equals(method)) return; throw new AccessDeniedException("no right");
登录接口
@PostMapping("/auth") @ApiOperation(value = "用户登录接口") public ApiResponse<String> auth(HttpServletRequest request,@RequestBody ReqLoginDto reqLoginDto) SysUser user= userService.login(reqLoginDto.getUserName(), reqLoginDto.getPassword()); //todo 异常捕获,返回错误信息 if (user==null) return ApiResponse.error("异常","登录异常"); //加载用户信息及权限 UserDetails userDetails = customUserService.loadUserByUsername(user.getUsername()); //生成满足spring security框架要求的登录信息 UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities()); authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); //保存在当前请求的SecurityContextHolder中 SecurityContextHolder.getContext().setAuthentication(authentication); return ApiResponse.ok("success");
完整的项目代码,除了登录可以在https://github.com/527515025/springBoot中的springboot-SpringSecurity3中找到
以上就实现了用户、角色、权限的动态管理,接下来我们简单的探究一下原理
以上是关于spring security使用和原理简析的主要内容,如果未能解决你的问题,请参考以下文章
Spring Security sec:使用 Java Config 授权标签
如何在 Spring Security thymeleaf sec 中使用列表:授权标签
Spring Security - Thymeleaf - 我可以在 sec:authorize 标签中评估 SPEL 表达式吗?