您好,登錄后才能下訂單哦!
這篇“SpringBoot結合JWT怎么實現登錄權限控制”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“SpringBoot結合JWT怎么實現登錄權限控制”文章吧。
首先我們需要導入使用到的jwt的包:
<dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>0.8.0</version> </dependency> <dependency> <groupId>com.auth0</groupId> <artifactId>java-jwt</artifactId> <version>3.2.0</version> </dependency>
LoginUser.java
public class LoginUser { private Integer userId; private String username; private String password; private String role; 生成getter和setter...... }
JwtUser.java
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.Collections; public class JwtUser implements UserDetails{ private Integer id; private String username; private String password; private Collection<? extends GrantedAuthority> authorities; public JwtUser(){ } public JwtUser(LoginUser loginUser){ this.id = loginUser.getUserId(); this.username = loginUser.getUsername(); this.password = loginUser.getPassword(); authorities = Collections.signleton(new SimpleGrantedAuthority(loginUser.getRole())); } @Override public Collection<? extends GrantedAuthority> getAuthorities(){ return authorities; } @Override public String getPassword(){ return password; } @Override public String getUsername(){ return username; } //賬號是否未過期 @Override public boolean isAccountNonExpired(){ return true; } //賬號是否未鎖定 @Override public boolean isAccountNonLocked(){ return true } //賬號憑證是否未過期 @Override public boolean isCredentialsNonExpired(){ return true; } @Override public boolean isEnabled(){ return true; } }
import com.bean.JwtUser; import io.jsonwebtoken.*; import org.springframework.security.core.userdetails.UserDetails; import java.util.Date; import java.util.HashMap; import java.util.Map; public class JwtTokenUtils { public static final String TOKEN_HEADER = "Authorization"; public static final String TOKEN_PREFIX = "Bearer "; public static final String SECRET = "jwtsecret"; public static final String ISS = "echisan"; private static final Long EXPIRATION = 60 * 60 * 3;//過期時間3小時 private static final String ROLE = "role"; //創建token public static String createToken(String username, String role, boolean isRememberMe){ Map map = new HashMap(); map.put(ROLE, role); return Jwts.builder() .signWith(SignatureAlgorithm.HS512, SECRET) .setClaims(map) .setIssuer(ISS) .setSubject(username) .setIssuedAt(new Date()) .setExpiration(new Date(System.currentTimeMillis() + expiration * 1000)) .compact(); } //從token中獲取用戶名(此處的token是指去掉前綴之后的) public static String getUserName(String token){ String username; try { username = getTokenBody(token).getSubject(); } catch ( Exception e){ username = null; } return username; } public static String getUserRole(String token){ return (String) getTokenBody(token).get(ROLE); } private static Claims getTokenBody(String token){ Claims claims = null; try{ claims = Jwts.parser().setSigningKey(SECRET).parseClaimsJws(token).getBody(); } catch(ExpiredJwtException e){ e.printStackTrace(); } catch(UnsupportedJwtException e){ e.printStackTrace(); } catch(MalformedJwtException e){ e.printStackTrace(); } catch(SignatureException e){ e.printStackTrace(); } catch(IllegalArgumentException e){ e.printStackTrace(); } } //是否已過期 public static boolean isExpiration(String token){ try{ return getTokenBody(token).getExpiration().before(new Date()); } catch(Exception e){ e.printStackTrace; } return true; } }
1.JWTAuthenticationFilter.java (驗證登錄)
public class JWTAuthenticationFilter extends UsernamePasswordAuthenticationFilter{ private AuthenticationManager authenticationManager; public JWTAuthenticationFilter(AuthenticationManager authenticationManager){ this.authenticationManager = authenticationManager; setAuthenticationFailureHandler(new FailHandler());//設置賬號密碼錯誤時的處理方式 } @Override public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException{ //從輸入流中獲取登錄的信息 String username = request.getParameter("username"); String password = request.getParameter("password"); return authenticationManager.authenticate( new UsernamePasswordAuthenticationToken(username, password, new ArrayList<>()) ); } @Override protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult ) throws IOException, ServletException{ JwtUser jwtUser = (JwtUser) authResult.getPrincipal(); Collection<? extends GrantedAuthority> authorities = jwtUser.getAuthorities(); String role = ""; for(GrantedAuthority authority : authorities){ role = authority.getAuthority(); } String token = JwtTokenUtils.createToken(jwtUser.getUsername, role, false); //返回創建成功的token //但是這里創建的token只是單純的token,按照jwt的規定, //最后請求的格式應該是 “Bearer token“。 response.addHeader(JwtTokenUtils.TOKEN_HEADER, JwtTokenUtils.TOKEN_PREFIX + token); } //@Override //protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, // AuthenticationException failed) throws IOException, ServletException { // response.getWriter().write("authentication failed, reason: " + failed.getMessage()); //} }
2.JWTAuthorizationFilter.java (鑒定權限)
public class JWTAuthorizationFilter extends BasicAuthenticationFilter{ public JWTAuthorizationFilter(AuthenticationManager authenticationManager){ super(authenticationManager); } @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException { String tokenHeader = request.getHeader(JwtTokenUtils.TOKEN_HEADER); //如果請求頭中沒有Authorization信息則直接放行了 if(tokenHeader == null || !tokenHeader.startsWith(JwtTokenUtils.TOKEN_PREFIX)){ chain.doFilter(request, response); return; } //如果請求頭中有token,則進行解析,并且設置認證信息 if(!JwtTokenUtils.isExpiration(tokenHeader.replace(JwtTokenUtils.TOKEN_PREFIX, “”))){ SecurityContextHolder.getContext().setAuthentication(getAuthentication(tokenHeader)); } chain.doFilter(request, response); } private UsernamePasswordAuthenticationToken getAuthentication(String tokenHeader){ String token = tokenHeader.replace(JwtTokenUtils.TOKEN_PREFIX, “”); String username = JwtTokenUtils.getUserName(token); if(username != null){ return new UsernamePasswordAuthenticationToken(username, null, new ArrayList<>()); } return null; } }
3.UserDetailsServiceImpl.java (查庫匹配賬號密碼)
import org.springframework.security.core.userdetails.UserDetailsService; @Service public class UserDetailsServiceImpl implements UserDetailsService{ @Autowired UserMapper userMapper; public BCryptPasswordEncoder bCryptPasswordEncoder(){ return new BCryptPasswordEncoder(); } @Override public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException { LoginUser loginUser = usersMapper.selectByUserAccount(s); loginUser.setPassword(bCryptPasswordEncoder().encode(loginUser.getPassword())); return new JwtUser(loginUser); } }
public class FailHandler extends SimpleUrlAuthenticationFailureHandler { @Override public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException { String errorMsg = exception.getMessage(); if(exception instanceof BadCredentialsException){ errorMsg = "用戶名或密碼錯誤"; } response.setHeader("content-type", "application/json"); response.getOutputStream().write(JSONObject.fromObject(new AjaxResult(errorMsg, false)).toString().getBytes("utf-8")); } }
這個類里規定了權限的相關信息
@Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true) public class SecurityConfig extends WebSecurityConfigurerAdapter{ @Autowired private UserDetailsService userDetailsService; @Bean public BCryptPasswordEncoder bCryptPasswordEncoder(){ return new BCryptPasswordEncoder(); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception{ auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder()); } @Override public void configure(WebSecurity web) throws Exception{ web.ignoring().antMatchers("/static/**"); } @Override protected void configure(HttpSecurity http) throws Exception{ http.cors().and().csrf().disable() .authorizeRequests() .antMatchers(HttpMethod.POST, "/login").permitAll()//都可以訪問 .antMatchers("/").permitAll() .antMatchers("/index.html").permitAll() .antMatchers("/*.js").permitAll() .antMatchers("/*.css").permitAll() .antMatchers("/*.png").permitAll() .antMatchers("/*.svg").permitAll() .antMatchers("/*.woff").permitAll() .antMatchers("/*.ttf").permitAll() .antMatchers("/*.eot").permitAll() .antMatchers("/test/*").permitAll()//對接口的權限控制,表示對于"/test"路徑下的所有接口無需登錄也可以訪問 .antMatchers("/swagger-ui.html", "/v2/api-docs", "/configuration/ui", "/swagger-resources", "/configuration/security", "/webjars/**", "/swagger-resources/configuration/ui").permitAll()//表示對swagger頁面放行 .anyRequest().authenticated()//表示其余所有請求需要登陸之后才能訪問 .and() .addFilter(new JWTAuthenticationFilter(authenticationManager())) .addFilter(new JWTAuthorizationFilter(authenticationManager())) .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); } @Bean CorsConfigurationSource corsConfigurationSource() { final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", new CorsConfiguration().applyPermitDefaultValues()); return source; } }
以上就是關于“SpringBoot結合JWT怎么實現登錄權限控制”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。