-
Notifications
You must be signed in to change notification settings - Fork 68
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #49 from emilioweber/ext_app_rsa_auth
Adding request filter
- Loading branch information
Showing
7 changed files
with
326 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
106 changes: 106 additions & 0 deletions
106
src/main/java/authentication/jwt/AuthenticationFilter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
package authentication.jwt; | ||
|
||
import authentication.SymExtensionAppRSAAuth; | ||
import configuration.SymConfig; | ||
import io.jsonwebtoken.Claims; | ||
import io.jsonwebtoken.Jws; | ||
import io.jsonwebtoken.JwtParser; | ||
import io.jsonwebtoken.Jwts; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
import java.io.IOException; | ||
import java.security.PublicKey; | ||
import java.security.cert.CertificateException; | ||
import java.util.regex.Pattern; | ||
|
||
import javax.servlet.Filter; | ||
import javax.servlet.FilterChain; | ||
import javax.servlet.FilterConfig; | ||
import javax.servlet.ServletException; | ||
import javax.servlet.ServletRequest; | ||
import javax.servlet.ServletResponse; | ||
import javax.servlet.http.HttpServletRequest; | ||
import javax.servlet.http.HttpServletResponse; | ||
|
||
public class AuthenticationFilter implements Filter { | ||
|
||
private static final String FILTER_INIT = "Starting authentication filter"; | ||
private static final String FILTER_DESTROY = "Destroying authentication filter"; | ||
private static final String AUTHORIZATION_HEADER = "Authorization"; | ||
private static final String AUTHORIZATION_HEADER_BEARER_PREFIX = "BEARER"; | ||
private static final String USER_INFO_PROPERTY = "user_info"; | ||
private static final String MISSING_JWT_MESSAGE = "Missing JWT"; | ||
private static final String UNAUTHORIZED_JWT_MESSAGE = "Unauthorized JWT"; | ||
private static final String INTERNAL_SERVER_ERROR_MESSAGE = | ||
"Unexpected error, please contact the system administrator"; | ||
private static final String USER_ID_FIELDNAME = "sub"; | ||
private static final String ANY_FOLLOWING_CHARACTER_PATTERN = ".*"; | ||
|
||
private SymExtensionAppRSAAuth rsaAuth; | ||
private SymConfig symConfig; | ||
private JwtParser parser = Jwts.parser(); | ||
|
||
private static final Logger LOGGER = LoggerFactory.getLogger(AuthenticationFilter.class); | ||
|
||
public AuthenticationFilter(SymExtensionAppRSAAuth rsaAuth, SymConfig symConfig) { | ||
this.rsaAuth = rsaAuth; | ||
this.symConfig = symConfig; | ||
} | ||
|
||
@Override | ||
public void init(FilterConfig filterConfig) throws ServletException { | ||
LoggerFactory.getLogger(AuthenticationFilter.class).info(FILTER_INIT); | ||
} | ||
|
||
@Override | ||
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, | ||
FilterChain filterChain) throws IOException, ServletException { | ||
HttpServletRequest request = (HttpServletRequest) servletRequest; | ||
HttpServletResponse response = (HttpServletResponse) servletResponse; | ||
|
||
if (Pattern.compile( | ||
symConfig.getAuthenticationFilterUrlPattern() + ANY_FOLLOWING_CHARACTER_PATTERN) | ||
.matcher(request.getServletPath()) | ||
.matches()) { | ||
String jwt = | ||
request.getHeader(AUTHORIZATION_HEADER) | ||
.substring(AUTHORIZATION_HEADER_BEARER_PREFIX.length()); | ||
if (jwt == null) { | ||
response.setStatus(401); | ||
response.getWriter().write(MISSING_JWT_MESSAGE); | ||
return; | ||
} | ||
|
||
Jws<Claims> jws; | ||
try { | ||
PublicKey rsaVerifier = rsaAuth.getPodPublicKey(); | ||
jws = parser.setSigningKey(rsaVerifier).parseClaimsJws(jwt); | ||
} catch (CertificateException e) { | ||
response.setStatus(401); | ||
response.getWriter().write(UNAUTHORIZED_JWT_MESSAGE); | ||
return; | ||
} | ||
|
||
try { | ||
new JwtPayload(); | ||
JwtPayload jwtPayload = new JwtPayload(); | ||
jwtPayload.setUserId(String.valueOf(jws.getBody().get(USER_ID_FIELDNAME))); | ||
request.setAttribute(USER_INFO_PROPERTY, jwtPayload); | ||
|
||
filterChain.doFilter(request, servletResponse); | ||
} catch (Exception e) { | ||
LOGGER.error(e.getMessage(), e); | ||
response.setStatus(500); | ||
response.getWriter().write(INTERNAL_SERVER_ERROR_MESSAGE); | ||
return; | ||
} | ||
} | ||
filterChain.doFilter(request, servletResponse); | ||
} | ||
|
||
@Override | ||
public void destroy() { | ||
LoggerFactory.getLogger(AuthenticationFilter.class).info(FILTER_DESTROY); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
package authentication.jwt; | ||
|
||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; | ||
import com.fasterxml.jackson.annotation.JsonProperty; | ||
|
||
@JsonIgnoreProperties(ignoreUnknown = true) | ||
public class JwtPayload { | ||
@JsonProperty("sub") | ||
private String userId; | ||
private JwtUser user; | ||
@JsonProperty("aud") | ||
private String applicationId; | ||
@JsonProperty("iss") | ||
private String companyName; | ||
@JsonProperty("exp") | ||
private Long expirationDateInSeconds; | ||
|
||
public JwtPayload() { | ||
} | ||
|
||
public String getUserId() { | ||
return userId; | ||
} | ||
|
||
public void setUserId(String userId) { | ||
this.userId = userId; | ||
} | ||
|
||
public JwtUser getUser() { | ||
return user; | ||
} | ||
|
||
public void setUser(JwtUser user) { | ||
this.user = user; | ||
} | ||
|
||
public String getApplicationId() { | ||
return applicationId; | ||
} | ||
|
||
public void setApplicationId(String applicationId) { | ||
this.applicationId = applicationId; | ||
} | ||
|
||
public String getCompanyName() { | ||
return companyName; | ||
} | ||
|
||
public void setCompanyName(String companyName) { | ||
this.companyName = companyName; | ||
} | ||
|
||
public Long getExpirationDateInSeconds() { | ||
return expirationDateInSeconds; | ||
} | ||
|
||
public void setExpirationDateInSeconds(Long expirationDateInSeconds) { | ||
this.expirationDateInSeconds = expirationDateInSeconds; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
package authentication.jwt; | ||
|
||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; | ||
|
||
@JsonIgnoreProperties(ignoreUnknown = true) | ||
public class JwtUser { | ||
private String id; | ||
private String emailAddress; | ||
private String username; | ||
private String firstName; | ||
private String lastName; | ||
private String displayName; | ||
private String title; | ||
private String company; | ||
private String companyId; | ||
private String location; | ||
private String avatarUrl; | ||
private String avatarSmallUrl; | ||
|
||
public JwtUser() { | ||
} | ||
|
||
public String getId() { | ||
return id; | ||
} | ||
|
||
public void setId(String id) { | ||
this.id = id; | ||
} | ||
|
||
public String getEmailAddress() { | ||
return emailAddress; | ||
} | ||
|
||
public void setEmailAddress(String emailAddress) { | ||
this.emailAddress = emailAddress; | ||
} | ||
|
||
public String getUsername() { | ||
return username; | ||
} | ||
|
||
public void setUsername(String username) { | ||
this.username = username; | ||
} | ||
|
||
public String getFirstName() { | ||
return firstName; | ||
} | ||
|
||
public void setFirstName(String firstName) { | ||
this.firstName = firstName; | ||
} | ||
|
||
public String getLastName() { | ||
return lastName; | ||
} | ||
|
||
public void setLastName(String lastName) { | ||
this.lastName = lastName; | ||
} | ||
|
||
public String getDisplayName() { | ||
return displayName; | ||
} | ||
|
||
public void setDisplayName(String displayName) { | ||
this.displayName = displayName; | ||
} | ||
|
||
public String getTitle() { | ||
return title; | ||
} | ||
|
||
public void setTitle(String title) { | ||
this.title = title; | ||
} | ||
|
||
public String getCompany() { | ||
return company; | ||
} | ||
|
||
public void setCompany(String company) { | ||
this.company = company; | ||
} | ||
|
||
public String getCompanyId() { | ||
return companyId; | ||
} | ||
|
||
public void setCompanyId(String companyId) { | ||
this.companyId = companyId; | ||
} | ||
|
||
public String getLocation() { | ||
return location; | ||
} | ||
|
||
public void setLocation(String location) { | ||
this.location = location; | ||
} | ||
|
||
public String getAvatarUrl() { | ||
return avatarUrl; | ||
} | ||
|
||
public void setAvatarUrl(String avatarUrl) { | ||
this.avatarUrl = avatarUrl; | ||
} | ||
|
||
public String getAvatarSmallUrl() { | ||
return avatarSmallUrl; | ||
} | ||
|
||
public void setAvatarSmallUrl(String avatarSmallUrl) { | ||
this.avatarSmallUrl = avatarSmallUrl; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters