最近看了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);
}
}
近期评论