Skip to content
This repository was archived by the owner on May 22, 2021. It is now read-only.

Commit d75b4a9

Browse files
committed
Added spring-auth module
1 parent c899ff6 commit d75b4a9

8 files changed

Lines changed: 259 additions & 0 deletions

File tree

pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
<module>scope</module>
1414
<module>auth</module>
1515
<module>util</module>
16+
<module>spring-auth</module>
1617
</modules>
1718

1819
<properties>

spring-auth/pom.xml

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
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>gewia-common</artifactId>
7+
<groupId>com.gewia.common</groupId>
8+
<version>1.0</version>
9+
</parent>
10+
<modelVersion>4.0.0</modelVersion>
11+
<artifactId>spring-auth</artifactId>
12+
13+
<dependencyManagement>
14+
<dependencies>
15+
<dependency>
16+
<groupId>org.springframework.boot</groupId>
17+
<artifactId>spring-boot-dependencies</artifactId>
18+
<version>2.1.10.RELEASE</version>
19+
<type>pom</type>
20+
<scope>import</scope>
21+
</dependency>
22+
</dependencies>
23+
</dependencyManagement>
24+
25+
<dependencies>
26+
<dependency>
27+
<groupId>com.gewia.common</groupId>
28+
<artifactId>auth</artifactId>
29+
<version>${project.parent.version}</version>
30+
<scope>compile</scope>
31+
</dependency>
32+
<dependency>
33+
<groupId>com.gewia.common</groupId>
34+
<artifactId>scope</artifactId>
35+
<version>${project.parent.version}</version>
36+
<scope>compile</scope>
37+
</dependency>
38+
39+
<dependency>
40+
<groupId>com.auth0</groupId>
41+
<artifactId>java-jwt</artifactId>
42+
<version>3.10.3</version>
43+
<scope>compile</scope>
44+
</dependency>
45+
46+
<dependency>
47+
<groupId>javax.validation</groupId>
48+
<artifactId>validation-api</artifactId>
49+
<version>2.0.1.Final</version>
50+
<scope>compile</scope>
51+
</dependency>
52+
53+
<!-- Spring -->
54+
<dependency>
55+
<groupId>org.springframework.boot</groupId>
56+
<artifactId>spring-boot-starter-web</artifactId>
57+
<exclusions>
58+
<exclusion>
59+
<groupId>org.springframework.boot</groupId>
60+
<artifactId>spring-boot-starter-logging</artifactId>
61+
</exclusion>
62+
</exclusions>
63+
</dependency>
64+
<dependency>
65+
<groupId>org.springframework.boot</groupId>
66+
<artifactId>spring-boot-starter-test</artifactId>
67+
<scope>test</scope>
68+
<exclusions>
69+
<exclusion>
70+
<groupId>org.junit.vintage</groupId>
71+
<artifactId>junit-vintage-engine</artifactId>
72+
</exclusion>
73+
</exclusions>
74+
</dependency>
75+
</dependencies>
76+
77+
</project>
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.gewia.common.spring.auth;
2+
3+
import java.lang.annotation.ElementType;
4+
import java.lang.annotation.Retention;
5+
import java.lang.annotation.RetentionPolicy;
6+
import java.lang.annotation.Target;
7+
8+
@Retention(RetentionPolicy.RUNTIME)
9+
@Target(ElementType.METHOD)
10+
public @interface Authentication {
11+
12+
String scope() default "";
13+
14+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package com.gewia.common.spring.auth;
2+
3+
import com.gewia.common.spring.auth.interceptor.AuthenticationInterceptor;
4+
import java.util.ArrayList;
5+
import java.util.List;
6+
import javax.annotation.PostConstruct;
7+
import lombok.Getter;
8+
9+
public abstract class SpringAuthentication {
10+
11+
@Getter private static List<AuthenticationInterceptor> authenticationInterceptors = new ArrayList<>();
12+
13+
@PostConstruct
14+
public void registerInterceptor() {
15+
authenticationInterceptors = this.addAuthenticationInterceptors(authenticationInterceptors);
16+
}
17+
18+
abstract public List<AuthenticationInterceptor> addAuthenticationInterceptors(List<AuthenticationInterceptor> authenticationInterceptors);
19+
20+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package com.gewia.common.spring.auth;
2+
3+
import com.auth0.jwt.interfaces.DecodedJWT;
4+
import com.gewia.common.spring.auth.interceptor.AuthenticationInterceptor;
5+
import java.util.List;
6+
import javax.servlet.http.HttpServletRequest;
7+
import org.springframework.context.annotation.Configuration;
8+
import org.springframework.core.MethodParameter;
9+
import org.springframework.web.bind.support.WebDataBinderFactory;
10+
import org.springframework.web.context.request.NativeWebRequest;
11+
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
12+
import org.springframework.web.method.support.ModelAndViewContainer;
13+
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
14+
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
15+
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
16+
17+
@Configuration
18+
@EnableWebMvc
19+
public class SpringAuthenticationWebConfig implements WebMvcConfigurer, HandlerMethodArgumentResolver {
20+
21+
@Override
22+
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
23+
return ((HttpServletRequest) webRequest.getNativeRequest()).getAttribute("accessToken");
24+
}
25+
26+
@Override
27+
public boolean supportsParameter(MethodParameter parameter) {
28+
return parameter.getParameterType().equals(DecodedJWT.class);
29+
}
30+
31+
@Override
32+
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
33+
resolvers.add(this);
34+
}
35+
36+
@Override
37+
public void addInterceptors(InterceptorRegistry registry) {
38+
for (AuthenticationInterceptor authenticationInterceptor : SpringAuthentication.getAuthenticationInterceptors())
39+
registry.addInterceptor(authenticationInterceptor).addPathPatterns("/**/*");
40+
}
41+
42+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package com.gewia.common.spring.auth.interceptor;
2+
3+
import com.gewia.common.spring.auth.Authentication;
4+
import org.springframework.web.method.HandlerMethod;
5+
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
6+
import java.lang.annotation.Annotation;
7+
import java.util.ArrayList;
8+
import java.util.List;
9+
10+
public class AuthenticationInterceptor extends HandlerInterceptorAdapter {
11+
12+
public List<Authentication> getAuthenticationAnnotations(Object handler) {
13+
HandlerMethod method = (HandlerMethod) handler;
14+
15+
List<Authentication> authentications = new ArrayList<>();
16+
for (Annotation annotation : method.getMethod().getAnnotations())
17+
if (annotation.annotationType().equals(Authentication.class))
18+
authentications.add((Authentication) annotation);
19+
20+
return authentications;
21+
}
22+
23+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package com.gewia.common.spring.auth.interceptor;
2+
3+
import com.auth0.jwt.interfaces.Claim;
4+
import com.auth0.jwt.interfaces.DecodedJWT;
5+
import com.gewia.common.auth.jwt.JwtUtil;
6+
import com.gewia.common.spring.auth.Authentication;
7+
import com.gewia.common.util.Pair;
8+
import java.util.List;
9+
import javax.servlet.http.HttpServletRequest;
10+
import javax.servlet.http.HttpServletResponse;
11+
import lombok.AllArgsConstructor;
12+
import org.springframework.http.HttpStatus;
13+
14+
@AllArgsConstructor
15+
public class AuthenticationScopeInterceptor extends AuthenticationInterceptor {
16+
17+
private JwtUtil jwtUtil;
18+
19+
@Override
20+
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
21+
response.setStatus(HttpStatus.FORBIDDEN.value());
22+
23+
List<Authentication> authentications = this.getAuthenticationAnnotations(handler);
24+
25+
if (authentications.isEmpty()) {
26+
response.setStatus(HttpStatus.OK.value());
27+
return true;
28+
}
29+
30+
String jwt = request.getHeader("Authorization");
31+
32+
Pair<DecodedJWT, JwtUtil.VerificationResult> result = this.jwtUtil.verify(jwt);
33+
34+
if (result.getRight() != JwtUtil.VerificationResult.SUCCESS) return false;
35+
36+
Claim claim = result.getLeft().getClaim("scopes");
37+
List<String> userScopes = claim.asList(String.class);
38+
for (Authentication authentication : authentications) {
39+
if (!authentication.scope().isBlank()) {
40+
boolean isPresent = false;
41+
for (String userScope : userScopes)
42+
if (userScope.equalsIgnoreCase(authentication.scope())) {
43+
isPresent = true;
44+
break;
45+
}
46+
if (!isPresent) return false;
47+
}
48+
}
49+
50+
response.setStatus(HttpStatus.OK.value());
51+
request.setAttribute("accessToken", result.getLeft());
52+
53+
return true;
54+
}
55+
56+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package com.gewia.common.spring.auth.interceptor;
2+
3+
import javax.servlet.http.HttpServletRequest;
4+
import javax.servlet.http.HttpServletResponse;
5+
import lombok.AllArgsConstructor;
6+
import org.springframework.http.HttpStatus;
7+
8+
@AllArgsConstructor
9+
public class AuthenticationServiceTokenInterceptor extends AuthenticationInterceptor {
10+
11+
private String serviceToken;
12+
13+
@Override
14+
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
15+
response.setStatus(HttpStatus.FORBIDDEN.value());
16+
17+
String serviceToken = request.getHeader("X-ServiceToken");
18+
19+
if (serviceToken == null) return false;
20+
if (!this.serviceToken.equals(serviceToken)) return false;
21+
22+
response.setStatus(HttpStatus.OK.value());
23+
return true;
24+
}
25+
26+
}

0 commit comments

Comments
 (0)