1 package com.atlassian.asap.core.server.springsecurity;
2
3 import com.atlassian.asap.api.Jwt;
4 import com.atlassian.asap.api.JwtBuilder;
5 import com.atlassian.asap.api.exception.CannotRetrieveKeyException;
6 import com.atlassian.asap.api.exception.InvalidTokenException;
7 import com.atlassian.asap.core.exception.PublicKeyNotFoundException;
8 import com.atlassian.asap.core.validator.JwtValidator;
9 import com.google.common.collect.ImmutableSet;
10 import org.slf4j.Logger;
11 import org.slf4j.LoggerFactory;
12 import org.springframework.security.authentication.AuthenticationProvider;
13 import org.springframework.security.authentication.AuthenticationServiceException;
14 import org.springframework.security.authentication.BadCredentialsException;
15 import org.springframework.security.core.Authentication;
16 import org.springframework.security.core.AuthenticationException;
17 import org.springframework.security.core.GrantedAuthority;
18 import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken;
19
20 import java.util.Collection;
21 import java.util.Collections;
22 import java.util.Objects;
23 import java.util.Set;
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40 public class AsapAuthenticationProvider implements AuthenticationProvider {
41 private static final Logger logger = LoggerFactory.getLogger(AsapAuthenticationProvider.class);
42
43 private final JwtValidator jwtValidator;
44 private final Set<GrantedAuthority> defaultAuthorities;
45
46 public AsapAuthenticationProvider(JwtValidator jwtValidator,
47 Collection<GrantedAuthority> defaultAuthorities) {
48 this.jwtValidator = Objects.requireNonNull(jwtValidator);
49 this.defaultAuthorities = ImmutableSet.copyOf(defaultAuthorities);
50 }
51
52 public AsapAuthenticationProvider(JwtValidator jwtValidator) {
53 this(jwtValidator, Collections.emptySet());
54 }
55
56 @Override
57 public final Authentication authenticate(Authentication authentication) throws AuthenticationException {
58 String serialisedJwt = (String) authentication.getCredentials();
59 try {
60 Jwt validJwt = jwtValidator.readAndValidate(serialisedJwt);
61 Collection<GrantedAuthority> grantedAuthorities = getGrantedAuthorities(validJwt);
62 return new PreAuthenticatedAuthenticationToken(
63 effectiveSubject(validJwt),
64 immutableAndSerializable(validJwt),
65 grantedAuthorities);
66 } catch (PublicKeyNotFoundException e) {
67 logger.debug("Public key not found", e);
68 throw new BadCredentialsException("Unable to verify token");
69 } catch (CannotRetrieveKeyException e) {
70 logger.error("Failed to retrieve public key", e);
71 throw new AuthenticationServiceException("Failed to retrieve public key");
72 } catch (InvalidTokenException e) {
73 logger.debug("Invalid token", e);
74 throw new BadCredentialsException("Invalid token");
75 }
76 }
77
78 private static Jwt immutableAndSerializable(Jwt jwt) {
79 return JwtBuilder.copyJwt(jwt).build();
80 }
81
82
83
84
85
86
87
88
89 protected Collection<GrantedAuthority> getGrantedAuthorities(Jwt validJwt) throws AuthenticationException {
90 return defaultAuthorities;
91 }
92
93
94
95
96
97 protected static String effectiveSubject(Jwt jwt) {
98 return jwt.getClaims().getSubject().orElse(jwt.getClaims().getIssuer());
99 }
100
101 @Override
102 public final boolean supports(Class<?> authentication) {
103 return UnverifiedBearerToken.class.isAssignableFrom(authentication);
104 }
105
106 protected Collection<GrantedAuthority> getDefaultAuthorities() {
107 return defaultAuthorities;
108 }
109 }