最近看了vuejs,看到了vue-auth中一个jwt-auth,发现几年不关注,前端完全是全新的领域了。
这里列下jwt相关的资源,供快速了解jwt.
https://jwt.io/introduction/
https://github.com/szerhusenBC/jwt-spring-security-demo
https://www.toptal.com/java/rest-security-with-jwt-spring-security-and-java
spring boot security如何集成JWT.
java相关的jwt库太多了。
apache有oltu
spring有spring-security-jwt
还有其它一些第三方开源库
1、服务器端添加 jwt 支持:
配置spring security
package com.elex.gm.spring; import java.security.SecureRandom; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.WebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import com.elex.gm.service.UserManager; import com.elex.gm.spring.jwt.JWTAuthenticationFilter; import com.elex.gm.spring.jwt.JWTLoginFilter; @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Bean public BCryptPasswordEncoder passwordEncoder() throws Exception { return passwordEncoder; } public void configure(WebSecurity web) throws Exception { web.ignoring().antMatchers("/static/**").antMatchers("/hello/**").antMatchers("/api/open/**"); }; @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/api/gm/**").hasAnyRole("ADMIN", "USER") .antMatchers("/api/user/**").hasAnyRole("USER") .and() .formLogin() .loginProcessingUrl("/api/user/login") .permitAll() .and() .logout() // .logoutUrl("/api/open/logout") .and() .httpBasic() .and() .addFilterBefore(new JWTLoginFilter("/api/user/login", authenticationManager()), UsernamePasswordAuthenticationFilter.class) .addFilterBefore(new JWTAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class); http.csrf().disable(); http.headers().frameOptions().disable(); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userManager).passwordEncoder(passwordEncoder); } @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { } @Autowired private UserManager userManager; private BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(16, new SecureRandom("j^E1)y*)HL2gT,es+ODa!0+j^L1I3+6I".getBytes())); }
JWTLoginFilter:
package com.elex.gm.spring.jwt; import java.io.IOException; import java.util.Map; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.http.HttpStatus; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; import org.springframework.security.jwt.Jwt; import org.springframework.security.jwt.JwtHelper; import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter; import com.alibaba.fastjson.JSON; import com.elex.gm.model.User; import com.google.common.collect.Lists; import com.google.common.collect.Maps; public class JWTLoginFilter extends AbstractAuthenticationProcessingFilter { public JWTLoginFilter(String defaultFilterProcessesUrl, AuthenticationManager authenticationManager) { super(defaultFilterProcessesUrl); setAuthenticationManager(authenticationManager); } @Override public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException { String username = request.getParameter("username"); String password = request.getParameter("password"); if (username == null) { username = ""; } else { username = username.trim(); } if (password == null) { password = ""; } else { password = password.trim(); } return getAuthenticationManager() .authenticate(new UsernamePasswordAuthenticationToken(username, password, Lists.newArrayList())); } @Override protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException { User user = (User) authResult.getPrincipal(); Map<String, Object> tokenMap = Maps.newHashMap(); tokenMap.put("id", user.getId()); tokenMap.put("name", user.getUsername()); tokenMap.put("roles", user.getRoles()); Jwt jwt = JwtHelper.encode(JSON.toJSONString(tokenMap), JWTKey.hmac); String token = jwt.getEncoded(); response.setHeader("Authorization", token); } @Override protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) throws IOException, ServletException { response.setStatus(HttpStatus.UNAUTHORIZED.value()); } }
JWTAuthentication:
package com.elex.gm.spring.jwt; import java.io.IOException; import java.util.List; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import org.apache.commons.lang3.StringUtils; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.jwt.Jwt; import org.springframework.security.jwt.JwtHelper; import org.springframework.web.filter.GenericFilterBean; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.google.common.collect.Lists; public class JWTAuthenticationFilter extends GenericFilterBean { private static final String JWT_HEADER = "Authorization"; @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { try { String token = ((HttpServletRequest) request).getHeader(JWT_HEADER); Jwt jwt = JwtHelper.decodeAndVerify(token, JWTKey.hmac); JSONObject json = JSON.parseObject(jwt.getClaims()); String username = json.getString("name"); String roles = json.getString("roles"); List<SimpleGrantedAuthority> list = Lists.newArrayList(); if (!StringUtils.isEmpty(roles)) { for (String role : roles.split(",")) { if (!StringUtils.isEmpty(role)) { list.add(new SimpleGrantedAuthority("ROLE_" + role)); } } } Authentication authentication = new UsernamePasswordAuthenticationToken(username, null, list); SecurityContextHolder.getContext().setAuthentication(authentication); } catch (Exception e) { // e.printStackTrace(); } chain.doFilter(request, response); } }
0 条评论。