您好,登錄后才能下訂單哦!
這篇“SpringBoot結(jié)合JWT怎么實(shí)現(xiàn)登錄權(quán)限控制”文章的知識(shí)點(diǎn)大部分人都不太理解,所以小編給大家總結(jié)了以下內(nèi)容,內(nèi)容詳細(xì),步驟清晰,具有一定的借鑒價(jià)值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來(lái)看看這篇“SpringBoot結(jié)合JWT怎么實(shí)現(xiàn)登錄權(quán)限控制”文章吧。
首先我們需要導(dǎo)入使用到的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; } //賬號(hào)是否未過(guò)期 @Override public boolean isAccountNonExpired(){ return true; } //賬號(hào)是否未鎖定 @Override public boolean isAccountNonLocked(){ return true } //賬號(hào)憑證是否未過(guò)期 @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;//過(guò)期時(shí)間3小時(shí) private static final String ROLE = "role"; //創(chuàng)建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(); } } //是否已過(guò)期 public static boolean isExpiration(String token){ try{ return getTokenBody(token).getExpiration().before(new Date()); } catch(Exception e){ e.printStackTrace; } return true; } }
1.JWTAuthenticationFilter.java (驗(yàn)證登錄)
public class JWTAuthenticationFilter extends UsernamePasswordAuthenticationFilter{ private AuthenticationManager authenticationManager; public JWTAuthenticationFilter(AuthenticationManager authenticationManager){ this.authenticationManager = authenticationManager; setAuthenticationFailureHandler(new FailHandler());//設(shè)置賬號(hào)密碼錯(cuò)誤時(shí)的處理方式 } @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); //返回創(chuàng)建成功的token //但是這里創(chuàng)建的token只是單純的token,按照jwt的規(guī)定, //最后請(qǐng)求的格式應(yīng)該是 “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 (鑒定權(quán)限)
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); //如果請(qǐng)求頭中沒(méi)有Authorization信息則直接放行了 if(tokenHeader == null || !tokenHeader.startsWith(JwtTokenUtils.TOKEN_PREFIX)){ chain.doFilter(request, response); return; } //如果請(qǐng)求頭中有token,則進(jìn)行解析,并且設(shè)置認(rèn)證信息 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 (查庫(kù)匹配賬號(hào)密碼)
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 = "用戶名或密碼錯(cuò)誤"; } response.setHeader("content-type", "application/json"); response.getOutputStream().write(JSONObject.fromObject(new AjaxResult(errorMsg, false)).toString().getBytes("utf-8")); } }
這個(gè)類里規(guī)定了權(quán)限的相關(guān)信息
@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()//都可以訪問(wèn) .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()//對(duì)接口的權(quán)限控制,表示對(duì)于"/test"路徑下的所有接口無(wú)需登錄也可以訪問(wèn) .antMatchers("/swagger-ui.html", "/v2/api-docs", "/configuration/ui", "/swagger-resources", "/configuration/security", "/webjars/**", "/swagger-resources/configuration/ui").permitAll()//表示對(duì)swagger頁(yè)面放行 .anyRequest().authenticated()//表示其余所有請(qǐng)求需要登陸之后才能訪問(wèn) .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; } }
以上就是關(guān)于“SpringBoot結(jié)合JWT怎么實(shí)現(xiàn)登錄權(quán)限控制”這篇文章的內(nèi)容,相信大家都有了一定的了解,希望小編分享的內(nèi)容對(duì)大家有幫助,若想了解更多相關(guān)的知識(shí)內(nèi)容,請(qǐng)關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。