2 * ============LICENSE_START=======================================================
3 * ONAP : ccsdk features
4 * ================================================================================
5 * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property.
7 * ================================================================================
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 * ============LICENSE_END=========================================================
22 package org.onap.ccsdk.features.sdnr.wt.oauthprovider;
24 import com.auth0.jwt.interfaces.DecodedJWT;
25 import java.io.IOException;
26 import org.apache.shiro.authc.AuthenticationException;
27 import org.apache.shiro.authc.AuthenticationInfo;
28 import org.apache.shiro.authc.AuthenticationToken;
29 import org.apache.shiro.authc.SimpleAuthenticationInfo;
30 import org.apache.shiro.authc.UsernamePasswordToken;
31 import org.apache.shiro.authz.AuthorizationInfo;
32 import org.apache.shiro.authz.SimpleAuthorizationInfo;
33 import org.apache.shiro.subject.PrincipalCollection;
34 import org.onap.ccsdk.features.sdnr.wt.oauthprovider.data.Config;
35 import org.onap.ccsdk.features.sdnr.wt.oauthprovider.providers.TokenCreator;
36 import org.opendaylight.aaa.api.shiro.principal.ODLPrincipal;
37 import org.apache.shiro.authc.BearerToken;
38 import org.opendaylight.aaa.shiro.realm.TokenAuthRealm;
39 import org.slf4j.Logger;
40 import org.slf4j.LoggerFactory;
42 public class OAuth2Realm extends TokenAuthRealm {
44 public static final String REALM_NAME = "OAuth2Realm";
45 private static final Logger LOG = LoggerFactory.getLogger(OAuth2Realm.class);
46 private final TokenCreator tokenCreator;
47 private final Config config;
49 public OAuth2Realm() throws IOException {
51 super.setName(REALM_NAME);
52 this.config = Config.getInstance();
53 this.tokenCreator = TokenCreator.getInstance(this.config);
54 LOG.info("instantiated");
58 public boolean supports(AuthenticationToken token) {
59 boolean supports = (token instanceof BearerToken)
60 || (this.config.doSupportOdlUsers() && (token instanceof UsernamePasswordToken));
61 LOG.debug("supports {} is {}", token == null ? null : token.getClass().getName(), supports);
66 public String getName() {
71 protected void assertCredentialsMatch(AuthenticationToken atoken, AuthenticationInfo ai)
72 throws AuthenticationException {
73 LOG.debug("assertCredentialsMatch");
74 if (atoken instanceof BearerToken) {
75 if (this.tokenCreator.verify(((BearerToken) atoken).getToken()) == null) {
76 throw new AuthenticationException("Credentials do not match");
78 } else if (this.config.doSupportOdlUsers() && (atoken instanceof UsernamePasswordToken)) {
81 throw new AuthenticationException("AuthenticationInfo is not an OAuth2AuthenticationInfo");
86 // check what I can do
88 protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg) {
90 LOG.debug("auth info in shiro");
91 Object principal = arg.getPrimaryPrincipal();
92 if (principal instanceof DecodedJWT) {
93 LOG.debug("detected jwt token");
95 DecodedJWT token = (DecodedJWT) arg.getPrimaryPrincipal();
96 String[] roles = token.getClaim("roles").asArray(String.class);
97 SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
98 for (String role : roles) {
99 LOG.trace("found role {} in token", role);
100 authorizationInfo.addRole(role);
102 return authorizationInfo;
103 } catch (ClassCastException e) {
104 LOG.error("Couldn't decode authorization request", e);
106 } else if (principal instanceof ODLPrincipal) {
107 LOG.debug("detected basic token");
108 ODLPrincipal odlPrincipal = (ODLPrincipal) principal;
109 return new SimpleAuthorizationInfo(odlPrincipal.getRoles());
111 return new SimpleAuthorizationInfo();
118 protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
120 LOG.debug("auth token in shiro:");
121 if (token instanceof UsernamePasswordToken && this.config.doSupportOdlUsers()) {
122 LOG.debug("basic auth token found");
123 return super.doGetAuthenticationInfo(token);
124 } else if (token instanceof BearerToken) {
125 LOG.debug("jwt token found");
126 BearerToken oauthToken = (BearerToken) token;
128 DecodedJWT jwt = this.tokenCreator.verify(oauthToken.getToken());
130 SimpleAuthenticationInfo authenticationInfo =
131 new SimpleAuthenticationInfo(jwt, token.getCredentials(), getName());
132 return authenticationInfo;
136 LOG.debug("no valid token found");
138 throw new AuthenticationException("unable to verify token " + token);