SpringBoot2.0整合SpringSecurity实现WEB JWT认证
2019-01-22 13:24
2006 查看
相信很多做技术的朋友都做过前后端分离项目,项目分离后认证就靠JWT,费话不多说,直接上干活(写的不好还请多多见谅,大牛请绕行)
直接上代码,项目为Maven项目,结构如图:
包分类如下:
com.api.config 相关配置类
com.api.ctrl controller层
com.api.entity 相关实体类
com.api.repo jpa仓库相关
com.api.serice service层相关
ApiApplication 为启动类
主要配置核心类如下:
JWTAuthenticationFilter
[code]package com.api.config; import com.api.entity.User; import com.api.repo.UserRepo; import io.jsonwebtoken.Jwts; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.ArrayList; public class JWTAuthenticationFilter extends BasicAuthenticationFilter { private UserRepo userRepo; public JWTAuthenticationFilter(AuthenticationManager authenticationManager,UserRepo userRepo) { super(authenticationManager); this.userRepo = userRepo; } @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException { String header = request.getHeader("Authorization"); //如果不包含Bearer则退出 if(header != null && !header.startsWith("Bearer")){ chain.doFilter(request,response); return; } UsernamePasswordAuthenticationToken authenticationToken = getAuthentication(request); SecurityContextHolder.getContext().setAuthentication(authenticationToken); chain.doFilter(request,response); } private UsernamePasswordAuthenticationToken getAuthentication(HttpServletRequest request) { String token = request.getHeader("Authorization"); if (token != null) { // parse the token. String user = Jwts.parser() .setSigningKey("HSMyJwtSecret".getBytes()) .parseClaimsJws(token.replace("Bearer ", "")) .getBody() .getSubject(); if (user != null) { Integer userId = Integer.valueOf(user.split(":")[0]); User currUser = userRepo.findById(userId).orElse(null); if(currUser != null){ return new UsernamePasswordAuthenticationToken(currUser, null, new ArrayList<>()); } return new UsernamePasswordAuthenticationToken(new User(), null, new ArrayList<>()); } } return null; } }
JWTLoginFilter
[code]package com.api.config; import com.api.entity.User; import com.fasterxml.jackson.databind.ObjectMapper; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; 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.web.authentication.UsernamePasswordAuthenticationFilter; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.ArrayList; import java.util.Date; public class JWTLoginFilter extends UsernamePasswordAuthenticationFilter { private AuthenticationManager authenticationManager; public JWTLoginFilter(AuthenticationManager authenticationManager){ this.authenticationManager = authenticationManager; } @Override public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { try { User user = new ObjectMapper().readValue(request.getInputStream(), User.class); return authenticationManager.authenticate( new UsernamePasswordAuthenticationToken( user.getUsername(), user.getPassword(), new ArrayList<>() ) ); }catch (Exception e){ throw new RuntimeException(e); } } @Override protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException { String token = Jwts.builder() .setSubject(((JwtUser) authResult.getPrincipal()).getUsername()) .setExpiration(new Date(System.currentTimeMillis() + 60 * 60 * 24 * 1000)) .signWith(SignatureAlgorithm.HS256,"HSMyJwtSecret".getBytes()) .compact(); response.addHeader("Authorization", "Bearer " + token); response.getOutputStream().println(token); } }
MyUserDetailService
[code]package com.api.config; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.authentication.AuthenticationProvider; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.GrantedAuthority; import org.springframework.stereotype.Component; import java.util.Collection; @Component public class MyAuthencationProvider implements AuthenticationProvider { @Autowired private MyUserDetailService myUserDetailService; @Override public Authentication aut 1cca7 henticate(Authentication authentication) throws AuthenticationException { String username = authentication.getPrincipal().toString();JwtUser jwtUser = (JwtUser) myUserDetailService.loadUserByUsername(username); Collection<? extends GrantedAuthority> authorities = jwtUser.getAuthorities(); return new UsernamePasswordAuthenticationToken(jwtUser, jwtUser.getPassword(), authorities); } @Override public boolean supports(Class<?> aClass) { return true; } }
MyUserDetailService
[code]package com.api.config; import com.api.entity.User; import com.api.repo.UserRepo; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.stereotype.Component; @Component public class MyUserDetailService implements UserDetailsService { @Autowired private UserRepo userRepo; @Override public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException { User user = userRepo.findFirstByUsername(s); if(user != null){JwtUser jwtUser = new JwtUser(String.format("%s:%s",String.valueOf(user.getId()),user.getUsername()),user.getPassword()); return jwtUser; } throw new UsernameNotFoundException("用户名未找到"); } }
WebSecurityConfig
[code]package com.api.config; import com.api.repo.UserRepo; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Order; import org.springframework.http.HttpMethod; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; 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; @Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true) @Order(-1) public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private MyAuthencationProvider myAuthencationProvider; @Autowired private UserRepo userRepo; @Override protected void configure(HttpSecurity http) throws Exception { http.cors().and().csrf().disable().authorizeRequests() .antMatchers(HttpMethod.POST, "/register").permitAll() .anyRequest().authenticated() .and() .addFilter(new JWTLoginFilter(authenticationManager())) .addFilter(new JWTAuthenticationFilter(authenticationManager(),userRepo)); } @Override public void configure(AuthenticationManagerBuilder auth) throws Exception { auth.authenticationProvider(myAuthencationProvider); } }
JwtUser
[code]package com.api.config; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.userdetails.UserDetails; import java.util.Collection; public class JwtUser implements UserDetails { private String username; private String password; public JwtUser(String username,String password){ this.username = username; this.password = password; } @Override public Collection<? extends GrantedAuthority> getAuthorities() { return null; } @Override public String getPassword() { return password; } @Override public String getUsername() { return username; } @Override public boolean isAccountNonExpired() { return false; } @Override public boolean isAccountNonLocked() { return false; } @Override public boolean isCredentialsNonExpired() { return false; } @Override public boolean isEnabled() { return false; } }
MyMvcConfigurer
[code]package com.api.config; import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.context.annotation.Configuration; import org.springframework.security.access.SecurityConfig; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration @AutoConfigureBefore(SecurityConfig.class) public class MyMvcConfigurer implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins("*") .allowedMethods("*") .allowedHeaders("*") .allowCredentials(true) .maxAge(3600); } }
以上为config包下全部内容
项目POM.xml配置如下
[code]<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.0.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.api</groupId> <artifactId>api</artifactId> <version>0.0.1-SNAPSHOT</version> <name>api</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>com.github.wenhao</groupId> <artifactId>jpa-spec</artifactId> <version>3.2.3</version> </dependency> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>4.3.1</version> </dependency> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>0.7.0</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.5.1</version> <configuration> <compilerArgs> <arg>-verbose</arg> <arg>-Xlint:all,-options,-path</arg> </compilerArgs> <source>1.8</source> <target>1.8</target> </configuration> </plugin> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <plugin> <artifactId>maven-jar-plugin</artifactId> <configuration> <archive> <manifest> <addClasspath>true</addClasspath> <classpathPrefix>lib/</classpathPrefix> <mainClass>com.api.ApiApplication</mainClass> </manifest> </archive> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <configuration> <delimiters> <delimiter>@</delimiter> <delimiter>#{*}</delimiter> <delimiter>#</delimiter> </delimiters> </configuration> </plugin> </plugins> </build> <repositories> <repository> <id>spring-snapshots</id> <name>Spring Snapshots</name> <url>https://repo.spring.io/snapshot</url> <snapshots> <enabled>true</enabled> </snapshots> </repository> <repository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/milestone</url> </repository> </repositories> <pluginRepositories> <pluginRepository> <id>spring-snapshots</id> <name>Spring Snapshots</name> <url>https://repo.spring.io/snapshot</url> <snapshots> <enabled>true</enabled> </snapshots> </pluginRepository> <pluginRepository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/milestone</url> </pluginRepository> </pluginRepositories> </project>
以下为其他包结构以及类文件
以上配置成功后即可以POST方式访问
http://localhost:8080/login?username=xxx&password=xx 认证成功后会在返回jwt,下次请求认证的资源在header里边带上Authorization Bearer xxxxxx
即可。
相关文章推荐
- Spring Boot整合JWT实现用户认证
- Spring Boot实战之Filter实现使用JWT进行接口认证 jwt(json web token) 用户发送按照约定,向服务端发送 Header、Payload 和 Signature,
- SpringBoot2.0整合SpringSecurity实现自定义表单登录
- 使用 Spring Boot 2.0 + WebFlux 实现 RESTful API功能
- Spring Boot实战之Filter实现使用JWT进行接口认证
- SpringBoot整合SpringSecurity简单实现登入登出从零搭建
- Spring Boot2.0整合ES5实现文章内容搜索实战
- SpringBoot整合Shiro实现登录认证的方法
- spring boot+jwt实现api的token认证详解
- Spring Boot实战之Filter实现使用JWT进行接口认证
- 使用SpringBoot整合Jersey 实现Restful webservice.可以同时使用springmvc。
- Spring Boot 2.0 利用 Spring Security 实现简单的OAuth2.0认证方式1
- spring boot 与shiro实战(三) 整合实现用户认证
- 详解Spring Boot实战之Filter实现使用JWT进行接口认证
- 使用SpringBoot + Ignite + JWT实现用户认证
- 从零实现 Spring Boot 2.0 整合 weixin-java-mp(weixin-java-tools) 获取 openId,用于微信授权
- SpringBoot整合MyBatis的web项目
- (十一)Spring Boot整合Mybatis使用druid实现多数据源自动切换
- springboot+webmagic实现java爬虫jdbc及mysql的方法
- 用Spring Boot & Cloud,Angular2快速搭建微服务web应用 - 实现RESTful CRUD