利用SpringSecurity和JWT实现mymes认证和授权(二)
16lz
2021-01-22
SpringBoot整合SpringSecurity和JWT实现mymes认证和授权(二)
接上一篇接上一篇,SpringSecurity的配置类相关依赖以及方法说明
- configure(HttpSecurity httpSecurity):用于拦截url路径、JWT过滤和异常处理
- configure(AuthenticationManagerBuilder auth):用于配置userDetailsService和PasswordEncoder
- JwtAuthenticationTokenFilter:在用户名和密码前添加过滤器,若有token,会根据token自行登录
- RestfulAccessDeniedHandler:在用户没有访问权限的时候,返回JSON格式的处理结果
- RestAuthenticationEntryPoint:在token失效或者没有登录情况下,返回JSON格式处理结果
- PasswordEncoder:SpringSecurity定义的用于对密码进行编码及比对的接口,目前使用的是BCryptPasswordEncoder;
- IgnoreUrlsConfig:用于从application.yml中获取不需要安全保护的资源路径
- UserDetailsService:SpringSecurity核心接口,获取用户信息
添加IgnoreUrlsConfig
package com.cn.mymes.utils.config;/* *Created by zbb on 2021/1/6 **/import lombok.Getter;import lombok.Setter;import org.springframework.boot.context.properties.ConfigurationProperties;import java.util.ArrayList;import java.util.List;/** * 用于配置不需要保护的资源路径 * */@Getter@Setter@ConfigurationProperties(prefix = "secure.ignored")public class IgnoreUrlsConfig { private List<String> urls = new ArrayList<>();}
在application.yml中配置下不需要安全保护的资源路径
secure: ignored: urls: #安全路径白名单 - /swagger-ui.html - /swagger-resources/** - /swagger/** - /**/v2/api-docs - /**/*.js - /**/*.css - /**/*.png - /**/*.ico - /webjars/springfox-swagger-ui/** - /actuator/** - /druid/** - /admin/login - /admin/register - /admin/info - /admin/logout
添加Token过滤器JwtAuthenticationTokenFilter
package com.cn.mymes.component;import com.cn.mymes.utils.JwtTokenUtil;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Value;import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;import org.springframework.security.core.context.SecurityContextHolder;import org.springframework.security.core.userdetails.UserDetails;import org.springframework.security.core.userdetails.UserDetailsService;import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;import org.springframework.web.filter.OncePerRequestFilter;import javax.servlet.FilterChain;import javax.servlet.ServletException;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;/** *token登录过滤器 * */public class JwtAuthenticationTokenFilter extends OncePerRequestFilter { private static final Logger LOGGER = LoggerFactory.getLogger(JwtAuthenticationTokenFilter.class); @Autowired private UserDetailsService userDetailsService; @Autowired private JwtTokenUtil jwtTokenUtil; @Value("${jwt.tokenHeader}") private String tokenHeader; @Value("${jwt.tokenHead}") private String tokenHead; @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException { String authHeader = request.getHeader(this.tokenHeader); if (authHeader != null && authHeader.startsWith(this.tokenHead)) { String authToken = authHeader.substring(this.tokenHead.length());// The part after "Bearer " String username = jwtTokenUtil.getUserNameFromToken(authToken); LOGGER.info("checking username:{}", username); if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) { UserDetails userDetails = this.userDetailsService.loadUserByUsername(username); if (jwtTokenUtil.validateToken(authToken, userDetails)) { UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities()); authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); LOGGER.info("authenticated user:{}", username); SecurityContextHolder.getContext().setAuthentication(authentication); } } } chain.doFilter(request, response); }}
添加无权访问时RestfulAccessDeniedHandler方法
package com.cn.mymes.component;import cn.hutool.json.JSONUtil;import com.cn.mymes.common.CommonResult;import org.springframework.security.access.AccessDeniedException;import org.springframework.security.web.access.AccessDeniedHandler;import javax.servlet.ServletException;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;/** *在没有权限访问时,返回自定义JSON格式结果 */public class RestfulAccessDeniedHandler implements AccessDeniedHandler{ @Override public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException e) throws IOException, ServletException { response.setHeader("Access-Control-Allow-Origin", "*"); response.setHeader("Cache-Control","no-cache"); response.setCharacterEncoding("UTF-8"); response.setContentType("application/json"); response.getWriter().println(JSONUtil.parse(CommonResult.forbidden(e.getMessage()))); response.getWriter().flush(); }}
添加未登录或者登录过期返回自定义结果的RestAuthenticationEntryPoint方法
package com.cn.mymes.component;import cn.hutool.json.JSONUtil;import com.cn.mymes.common.CommonResult;import org.springframework.security.core.AuthenticationException;import org.springframework.security.web.AuthenticationEntryPoint;import javax.servlet.ServletException;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;/** * 未登录或者登录过期时,返回自定义JSON格式 */public class RestAuthenticationEntryPoint implements AuthenticationEntryPoint { @Override public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException { response.setHeader("Access-Control-Allow-Origin", "*"); response.setHeader("Cache-Control","no-cache"); response.setCharacterEncoding("UTF-8"); response.setContentType("application/json"); response.getWriter().println(JSONUtil.parse(CommonResult.unauthorized(authException.getMessage()))); response.getWriter().flush(); }}
添加SpringSecurity核心接口,获取用户信息
package com.cn.mymes.domain;import com.cn.mymes.mgb.model.UmsAdmin;import com.cn.mymes.mgb.model.UmsResource;import org.springframework.security.core.GrantedAuthority;import org.springframework.security.core.authority.SimpleGrantedAuthority;import org.springframework.security.core.userdetails.UserDetails;import java.util.Collection;import java.util.List;import java.util.stream.Collectors;/** * SpringSecurity核心,获取用户信息 * */public class AdminUserDetails implements UserDetails { private UmsAdmin umsAdmin; private List<UmsResource> resourceList; public AdminUserDetails(UmsAdmin umsAdmin, List<UmsResource> resourceList) { this.umsAdmin = umsAdmin; this.resourceList = resourceList; } @Override public Collection<? extends GrantedAuthority> getAuthorities() { //返回当前用户的角色 return resourceList.stream() .map(role ->new SimpleGrantedAuthority(role.getId()+":"+role.getName())) .collect(Collectors.toList()); } @Override public String getPassword() { return umsAdmin.getPassword(); } @Override public String getUsername() { return umsAdmin.getUsername(); } @Override public boolean isAccountNonExpired() { return true; } @Override public boolean isAccountNonLocked() { return true; } @Override public boolean isCredentialsNonExpired() { return true; } @Override public boolean isEnabled() { return umsAdmin.getStatus().equals(1); }}
明天讲MyMes中SpringSecurity项目权限管理中动态管理部分的实现
公众号
更多相关文章
- 算法:有向无环图的最短路径
- jQuery编程基础精华02(属性、表单过滤器,元素的each,表单选择器,子元
- jquery为属性过滤器动态添加值?
- jQuery学习笔记--选择器、过滤器片
- XHTML 相对路径与绝对路径
- CSS文件filemtime没有调用路径两次
- 如何定义两个日期之间的Kendo网格列过滤器?
- JSP页面图片路径为中文时乱码解决办法
- html页面中给img标签的src属性赋值为一张图片的存储路径,图片不显