View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.syncope.core.spring.security;
20  
21  import com.nimbusds.jwt.JWTClaimsSet;
22  import java.util.Collection;
23  import java.util.HashSet;
24  import java.util.Optional;
25  import java.util.Set;
26  import java.util.stream.Collectors;
27  import org.apache.commons.lang3.StringUtils;
28  import org.apache.commons.lang3.builder.EqualsBuilder;
29  import org.apache.commons.lang3.builder.HashCodeBuilder;
30  import org.springframework.security.core.Authentication;
31  
32  /**
33   * Represents the token for an authentication request or for an authenticated principal as JSON Web Token,
34   * once the request has been processed by the
35   * {@link org.springframework.security.authentication.AuthenticationManager#authenticate(Authentication)} method.
36   */
37  public class JWTAuthentication implements Authentication {
38  
39      private static final long serialVersionUID = -2013733709281305394L;
40  
41      private final JWTClaimsSet claims;
42  
43      private final SyncopeAuthenticationDetails details;
44  
45      private String username;
46  
47      private final Set<SyncopeGrantedAuthority> authorities = new HashSet<>();
48  
49      private boolean authenticated = false;
50  
51      public JWTAuthentication(final JWTClaimsSet claims, final SyncopeAuthenticationDetails details) {
52          this.claims = claims;
53          this.details = details;
54      }
55  
56      public JWTClaimsSet getClaims() {
57          return claims;
58      }
59  
60      @Override
61      public Collection<SyncopeGrantedAuthority> getAuthorities() {
62          return authorities;
63      }
64  
65      @Override
66      public Object getCredentials() {
67          return StringUtils.EMPTY;
68      }
69  
70      @Override
71      public SyncopeAuthenticationDetails getDetails() {
72          return details;
73      }
74  
75      @Override
76      public Object getPrincipal() {
77          return Optional.ofNullable(username).orElseGet(claims::getSubject);
78      }
79  
80      public void setUsername(final String username) {
81          this.username = username;
82      }
83  
84      @Override
85      public boolean isAuthenticated() {
86          return authenticated;
87      }
88  
89      @Override
90      public void setAuthenticated(final boolean authenticated) throws IllegalArgumentException {
91          this.authenticated = authenticated;
92      }
93  
94      @Override
95      public String getName() {
96          return Optional.ofNullable(username).orElseGet(claims::getSubject);
97      }
98  
99      @Override
100     public int hashCode() {
101         return new HashCodeBuilder().
102                 append(claims).
103                 append(details).
104                 append(username).
105                 append(authorities).
106                 append(authenticated).
107                 build();
108     }
109 
110     @Override
111     public boolean equals(final Object obj) {
112         if (this == obj) {
113             return true;
114         }
115         if (obj == null) {
116             return false;
117         }
118         if (getClass() != obj.getClass()) {
119             return false;
120         }
121         final JWTAuthentication other = (JWTAuthentication) obj;
122         return new EqualsBuilder().
123                 append(claims, other.claims).
124                 append(details, other.details).
125                 append(username, other.username).
126                 append(authorities, other.authorities).
127                 append(authenticated, other.authenticated).
128                 build();
129     }
130 
131     @Override
132     public String toString() {
133         StringBuilder sb = new StringBuilder();
134         sb.append(super.toString()).append(": ");
135         sb.append("Principal: ").append(this.getPrincipal()).append("; ");
136         sb.append("Authenticated: ").append(this.isAuthenticated()).append("; ");
137         sb.append("Details: ").append(this.getDetails()).append("; ");
138 
139         if (!authorities.isEmpty()) {
140             sb.append("Granted Authorities: ");
141             sb.append(authorities.stream().map(SyncopeGrantedAuthority::toString).collect(Collectors.joining(", ")));
142         } else {
143             sb.append("Not granted any authorities");
144         }
145 
146         return sb.toString();
147     }
148 }