[CXF-7344] Fix for jms rest problem. Convert dots to underscores
[cxf.git] / rt / rs / security / jose-parent / jose-jaxrs / src / main / java / org / apache / cxf / rs / security / jose / jaxrs / JwtAuthenticationFilter.java
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.cxf.rs.security.jose.jaxrs;
20
21 import java.io.IOException;
22 import java.util.logging.Logger;
23
24 import javax.annotation.Priority;
25 import javax.ws.rs.Priorities;
26 import javax.ws.rs.container.ContainerRequestContext;
27 import javax.ws.rs.container.ContainerRequestFilter;
28 import javax.ws.rs.container.PreMatching;
29 import javax.ws.rs.core.HttpHeaders;
30
31 import org.apache.cxf.common.logging.LogUtils;
32 import org.apache.cxf.jaxrs.utils.JAXRSUtils;
33 import org.apache.cxf.message.Message;
34 import org.apache.cxf.message.MessageUtils;
35 import org.apache.cxf.rs.security.jose.common.JoseConstants;
36 import org.apache.cxf.rs.security.jose.common.JoseException;
37 import org.apache.cxf.rs.security.jose.jwa.SignatureAlgorithm;
38 import org.apache.cxf.rs.security.jose.jwt.AbstractJoseJwtConsumer;
39 import org.apache.cxf.rs.security.jose.jwt.JwtToken;
40 import org.apache.cxf.rs.security.jose.jwt.JwtUtils;
41 import org.apache.cxf.security.SecurityContext;
42
43 @PreMatching
44 @Priority(Priorities.AUTHENTICATION)
45 public class JwtAuthenticationFilter extends AbstractJoseJwtConsumer implements ContainerRequestFilter {
46 protected static final Logger LOG = LogUtils.getL7dLogger(JwtAuthenticationFilter.class);
47
48 private static final String DEFAULT_AUTH_SCHEME = "JWT";
49 private String expectedAuthScheme = DEFAULT_AUTH_SCHEME;
50 private int clockOffset;
51 private String roleClaim;
52 private int ttl;
53
54 @Override
55 public void filter(ContainerRequestContext requestContext) throws IOException {
56 String auth = requestContext.getHeaderString(HttpHeaders.AUTHORIZATION);
57 String[] parts = auth == null ? null : auth.split(" ");
58 if (parts == null || !expectedAuthScheme.equals(parts[0]) || parts.length != 2) {
59 throw new JoseException(expectedAuthScheme + " scheme is expected");
60 }
61 JwtToken token = super.getJwtToken(parts[1]);
62
63 SecurityContext securityContext = configureSecurityContext(token);
64 if (securityContext != null) {
65 JAXRSUtils.getCurrentMessage().put(SecurityContext.class, securityContext);
66 }
67 }
68
69 protected SecurityContext configureSecurityContext(JwtToken jwt) {
70 Message m = JAXRSUtils.getCurrentMessage();
71 boolean enableUnsignedJwt =
72 MessageUtils.getContextualBoolean(m, JoseConstants.ENABLE_UNSIGNED_JWT_PRINCIPAL, false);
73
74 // The token must be signed/verified with a public key to set up the security context,
75 // unless we directly configure otherwise
76 if (isVerifiedWithAPublicKey(jwt) || enableUnsignedJwt) {
77 return new JwtTokenSecurityContext(jwt, roleClaim);
78 }
79 return null;
80 }
81
82 private boolean isVerifiedWithAPublicKey(JwtToken jwt) {
83 if (isJwsRequired()) {
84 String alg = (String)jwt.getJwsHeader(JoseConstants.HEADER_ALGORITHM);
85 SignatureAlgorithm sigAlg = SignatureAlgorithm.getAlgorithm(alg);
86 return SignatureAlgorithm.isPublicKeyAlgorithm(sigAlg);
87 }
88
89 return false;
90 }
91
92
93 public void setExpectedAuthScheme(String expectedAuthScheme) {
94 this.expectedAuthScheme = expectedAuthScheme;
95 }
96
97 @Override
98 protected void validateToken(JwtToken jwt) {
99 JwtUtils.validateTokenClaims(jwt.getClaims(), ttl, clockOffset, true);
100 }
101
102 public int getClockOffset() {
103 return clockOffset;
104 }
105
106 public void setClockOffset(int clockOffset) {
107 this.clockOffset = clockOffset;
108 }
109
110 public String getRoleClaim() {
111 return roleClaim;
112 }
113
114 public void setRoleClaim(String roleClaim) {
115 this.roleClaim = roleClaim;
116 }
117
118 public int getTtl() {
119 return ttl;
120 }
121
122 public void setTtl(int ttl) {
123 this.ttl = ttl;
124 }
125 }