Skip to content

Commit 864bd23

Browse files
author
haiji.yang
committed
add SecurityApp ➕ 🆕
1 parent 79646f1 commit 864bd23

22 files changed

+874
-3
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -46,5 +46,6 @@
4646
| spring-event-demo | spring 企业级事件应用 |
4747
| spring-spel-demo | sping SPEL 企业级开发相关 |
4848
| security-demo | security 安全认证实现RBAC |
49+
| security-token-demo | security + token 安全认证实现RBAC |
4950
| webflux-demo | 响应式编程 |
5051
| websocket-demo | websocket相关 |

pom.xml

+3-1
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,12 @@
4848
<module>api-key-demo</module>
4949
<module>flyway-demo</module>
5050
<module>security-demo</module>
51+
<module>security-token-demo</module>
52+
<module>testng-demo</module>
5153
</modules>
5254

5355
<properties>
54-
<java.version>8</java.version>
56+
<java.version>14</java.version>
5557
<spring-boot.version>2.3.1.RELEASE</spring-boot.version>
5658
<maven.compiler.source.version>14</maven.compiler.source.version>
5759
<maven.compiler.target.version>14</maven.compiler.target.version>

security-demo/src/main/resources/application.properties

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
# Database Configuration
2-
spring.datasource.url=jdbc:postgresql://40.73.101.80:55432/digtal_lrp?rewriteBatchedStatements=true
2+
spring.datasource.url=jdbc:postgresql://localhost:55432/test?rewriteBatchedStatements=true
33
spring.datasource.driver-class-name=org.postgresql.Driver
44
spring.datasource.username=postgres
5-
spring.datasource.password=bmw.Pandor@2019
5+
spring.datasource.password=postgres
66
spring.jpa.show-sql=true
77
spring.jpa.hibernate.ddl-auto=update
88
spring.jpa.hibernate.naming-strategy=org.hibernate.cfg.ImprovedNamingStrategy

security-token-demo/pom.xml

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<parent>
6+
<artifactId>advanced-demo</artifactId>
7+
<groupId>com.javayh.advanced</groupId>
8+
<version>1.0.0.RELEASE</version>
9+
</parent>
10+
<modelVersion>4.0.0</modelVersion>
11+
12+
<artifactId>security-token-demo</artifactId>
13+
14+
<dependencies>
15+
<dependency>
16+
<groupId>org.springframework.boot</groupId>
17+
<artifactId>spring-boot-starter-security</artifactId>
18+
</dependency>
19+
<dependency>
20+
<groupId>org.springframework.boot</groupId>
21+
<artifactId>spring-boot-starter-data-jpa</artifactId>
22+
</dependency>
23+
<dependency>
24+
<groupId>org.postgresql</groupId>
25+
<artifactId>postgresql</artifactId>
26+
</dependency>
27+
<dependency>
28+
<groupId>io.jsonwebtoken</groupId>
29+
<artifactId>jjwt</artifactId>
30+
<version>0.9.1</version>
31+
</dependency>
32+
</dependencies>
33+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package com.javayh.security;
2+
3+
import org.springframework.boot.SpringApplication;
4+
import org.springframework.boot.autoconfigure.SpringBootApplication;
5+
6+
/**
7+
* <p>
8+
*
9+
* </p>
10+
*
11+
* @author Dylan
12+
* @version 1.0.0
13+
* @since 2021-12-08
14+
*/
15+
@SpringBootApplication
16+
public class SecurityTokenApp {
17+
public static void main(String[] args) {
18+
SpringApplication.run(SecurityTokenApp.class, args);
19+
}
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package com.javayh.security.token.config;
2+
3+
import java.io.IOException;
4+
5+
import javax.servlet.ServletException;
6+
import javax.servlet.http.HttpServletRequest;
7+
import javax.servlet.http.HttpServletResponse;
8+
9+
import org.slf4j.Logger;
10+
import org.slf4j.LoggerFactory;
11+
import org.springframework.security.core.AuthenticationException;
12+
import org.springframework.security.web.AuthenticationEntryPoint;
13+
import org.springframework.stereotype.Component;
14+
15+
/**
16+
* @author haiyang
17+
*/
18+
@Component
19+
public class AuthEntryPointJwt implements AuthenticationEntryPoint {
20+
21+
private static final Logger logger = LoggerFactory.getLogger(AuthEntryPointJwt.class);
22+
23+
@Override
24+
public void commence(HttpServletRequest request, HttpServletResponse response,
25+
AuthenticationException authException) throws IOException, ServletException {
26+
logger.error("Unauthorized error: {}", authException.getMessage());
27+
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Error: Unauthorized");
28+
}
29+
30+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package com.javayh.security.token.config;
2+
3+
import java.io.IOException;
4+
5+
import javax.servlet.FilterChain;
6+
import javax.servlet.ServletException;
7+
import javax.servlet.http.HttpServletRequest;
8+
import javax.servlet.http.HttpServletResponse;
9+
10+
import com.javayh.security.token.service.UserDetailsServiceImpl;
11+
import org.slf4j.Logger;
12+
import org.slf4j.LoggerFactory;
13+
import org.springframework.beans.factory.annotation.Autowired;
14+
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
15+
import org.springframework.security.core.context.SecurityContextHolder;
16+
import org.springframework.security.core.userdetails.UserDetails;
17+
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
18+
import org.springframework.util.StringUtils;
19+
import org.springframework.web.filter.OncePerRequestFilter;
20+
21+
22+
public class AuthTokenFilter extends OncePerRequestFilter {
23+
@Autowired
24+
private JwtUtils jwtUtils;
25+
26+
@Autowired
27+
private UserDetailsServiceImpl userDetailsService;
28+
29+
private static final Logger logger = LoggerFactory.getLogger(AuthTokenFilter.class);
30+
31+
@Override
32+
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
33+
throws ServletException, IOException {
34+
try {
35+
String jwt = parseJwt(request);
36+
if (jwt != null && jwtUtils.validateJwtToken(jwt)) {
37+
String username = jwtUtils.getUserNameFromJwtToken(jwt);
38+
39+
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
40+
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
41+
userDetails, null, userDetails.getAuthorities());
42+
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
43+
44+
SecurityContextHolder.getContext().setAuthentication(authentication);
45+
}
46+
} catch (Exception e) {
47+
logger.error("Cannot set user authentication: {}", e);
48+
}
49+
50+
filterChain.doFilter(request, response);
51+
}
52+
53+
private String parseJwt(HttpServletRequest request) {
54+
String headerAuth = request.getHeader("Authorization");
55+
56+
if (StringUtils.hasText(headerAuth) && headerAuth.startsWith("Bearer ")) {
57+
return headerAuth.substring(7, headerAuth.length());
58+
}
59+
60+
return null;
61+
}
62+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package com.javayh.security.token.config;
2+
3+
import com.javayh.security.token.model.UserDetailsImpl;
4+
import io.jsonwebtoken.*;
5+
import org.slf4j.Logger;
6+
import org.slf4j.LoggerFactory;
7+
import org.springframework.security.core.Authentication;
8+
import org.springframework.stereotype.Component;
9+
10+
import java.util.Date;
11+
12+
/**
13+
* @author haiyang
14+
*/
15+
@Component
16+
public class JwtUtils {
17+
private static final Logger logger = LoggerFactory.getLogger(JwtUtils.class);
18+
19+
private String jwtSecret = "demo";
20+
/**
21+
* Token 有效时长
22+
*/
23+
private static final Long EXPIRATION = 604800L;
24+
25+
private int jwtExpirationMs = 123456;
26+
27+
public String generateJwtToken(Authentication authentication) {
28+
UserDetailsImpl userPrincipal = (UserDetailsImpl) authentication.getPrincipal();
29+
return Jwts.builder()
30+
.setSubject((userPrincipal.getUsername()))
31+
.setIssuedAt(new Date())
32+
.setExpiration(new Date(System.currentTimeMillis() + EXPIRATION * 1000))
33+
.signWith(SignatureAlgorithm.HS512, jwtSecret)
34+
.compact();
35+
}
36+
37+
public String getUserNameFromJwtToken(String token) {
38+
return Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(token).getBody().getSubject();
39+
}
40+
41+
public boolean validateJwtToken(String authToken) {
42+
try {
43+
Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(authToken);
44+
return true;
45+
} catch (SignatureException e) {
46+
logger.error("Invalid JWT signature: {}", e.getMessage());
47+
} catch (MalformedJwtException e) {
48+
logger.error("Invalid JWT token: {}", e.getMessage());
49+
} catch (ExpiredJwtException e) {
50+
logger.error("JWT token is expired: {}", e.getMessage());
51+
} catch (UnsupportedJwtException e) {
52+
logger.error("JWT token is unsupported: {}", e.getMessage());
53+
} catch (IllegalArgumentException e) {
54+
logger.error("JWT claims string is empty: {}", e.getMessage());
55+
}
56+
57+
return false;
58+
}
59+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package com.javayh.security.token.config;
2+
3+
import com.javayh.security.token.service.UserDetailsServiceImpl;
4+
import org.springframework.beans.factory.annotation.Autowired;
5+
import org.springframework.context.annotation.Bean;
6+
import org.springframework.context.annotation.Configuration;
7+
import org.springframework.security.authentication.AuthenticationManager;
8+
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
9+
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
10+
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
11+
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
12+
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
13+
import org.springframework.security.config.http.SessionCreationPolicy;
14+
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
15+
import org.springframework.security.crypto.password.PasswordEncoder;
16+
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
17+
18+
19+
/**
20+
* @author haiyang
21+
*/
22+
@Configuration
23+
@EnableWebSecurity
24+
@EnableGlobalMethodSecurity(
25+
// securedEnabled = true,
26+
// jsr250Enabled = true,
27+
prePostEnabled = true)
28+
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
29+
@Autowired
30+
UserDetailsServiceImpl userDetailsService;
31+
32+
@Autowired
33+
private AuthEntryPointJwt unauthorizedHandler;
34+
35+
@Bean
36+
public AuthTokenFilter authenticationJwtTokenFilter() {
37+
return new AuthTokenFilter();
38+
}
39+
40+
@Override
41+
public void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
42+
authenticationManagerBuilder.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
43+
}
44+
45+
@Bean
46+
@Override
47+
public AuthenticationManager authenticationManagerBean() throws Exception {
48+
return super.authenticationManagerBean();
49+
}
50+
51+
@Bean
52+
public PasswordEncoder passwordEncoder() {
53+
return new BCryptPasswordEncoder();
54+
}
55+
56+
@Override
57+
protected void configure(HttpSecurity http) throws Exception {
58+
http.cors().and().csrf().disable()
59+
.exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
60+
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
61+
.authorizeRequests()
62+
.antMatchers("/api/auth/**").permitAll()
63+
.antMatchers("/api/test/**").permitAll()
64+
.anyRequest().authenticated();
65+
66+
http.addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class);
67+
}
68+
}

0 commit comments

Comments
 (0)