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.data.InvalidConfigurationException;
36 import org.onap.ccsdk.features.sdnr.wt.oauthprovider.providers.TokenCreator;
37 import org.opendaylight.aaa.api.shiro.principal.ODLPrincipal;
38 import org.apache.shiro.authc.BearerToken;
39 import org.opendaylight.aaa.shiro.realm.TokenAuthRealm;
40 import org.slf4j.Logger;
41 import org.slf4j.LoggerFactory;
43 public class OAuth2Realm extends TokenAuthRealm {
45 public static final String REALM_NAME = "OAuth2Realm";
46 private static final Logger LOG = LoggerFactory.getLogger(OAuth2Realm.class);
47 private final TokenCreator tokenCreator;
48 private final Config config;
50 public OAuth2Realm() throws IllegalArgumentException, IOException, InvalidConfigurationException {
52 super.setName(REALM_NAME);
53 this.config = Config.getInstance();
54 this.tokenCreator = TokenCreator.getInstance(this.config);
55 LOG.info("instantiated");
59 public boolean supports(AuthenticationToken token) {
60 boolean supports = (token instanceof BearerToken)
61 || (this.config.doSupportOdlUsers() && (token instanceof UsernamePasswordToken));
62 LOG.debug("supports {} is {}", token == null ? null : token.getClass().getName(), supports);
67 public String getName() {
72 protected void assertCredentialsMatch(AuthenticationToken atoken, AuthenticationInfo ai)
73 throws AuthenticationException {
74 LOG.debug("assertCredentialsMatch");
75 if (atoken instanceof BearerToken) {
76 if (this.tokenCreator.verify(((BearerToken) atoken).getToken()) == null) {
77 throw new AuthenticationException("Credentials do not match");
79 } else if (this.config.doSupportOdlUsers() && (atoken instanceof UsernamePasswordToken)) {
82 throw new AuthenticationException("AuthenticationInfo is not an OAuth2AuthenticationInfo");
87 // check what I can do
89 protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg) {
91 LOG.debug("auth info in shiro");
92 Object principal = arg.getPrimaryPrincipal();
93 if (principal instanceof DecodedJWT) {
94 LOG.debug("detected jwt token");
96 DecodedJWT token = (DecodedJWT) arg.getPrimaryPrincipal();
97 String[] roles = token.getClaim("roles").asArray(String.class);
98 SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
99 for (String role : roles) {
100 LOG.trace("found role {} in token", role);
101 authorizationInfo.addRole(role);
103 return authorizationInfo;
104 } catch (ClassCastException e) {
105 LOG.error("Couldn't decode authorization request", e);
107 } else if (principal instanceof ODLPrincipal) {
108 LOG.debug("detected basic token");
109 ODLPrincipal odlPrincipal = (ODLPrincipal) principal;
110 return new SimpleAuthorizationInfo(odlPrincipal.getRoles());
112 return new SimpleAuthorizationInfo();
119 protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
121 LOG.debug("auth token in shiro:");
122 if (token instanceof UsernamePasswordToken && this.config.doSupportOdlUsers()) {
123 LOG.debug("basic auth token found");
124 return super.doGetAuthenticationInfo(token);
125 } else if (token instanceof BearerToken) {
126 LOG.debug("jwt token found");
127 BearerToken oauthToken = (BearerToken) token;
129 DecodedJWT jwt = this.tokenCreator.verify(oauthToken.getToken());
131 SimpleAuthenticationInfo authenticationInfo =
132 new SimpleAuthenticationInfo(jwt, token.getCredentials(), getName());
133 return authenticationInfo;
137 LOG.debug("no valid token found");
139 throw new AuthenticationException("unable to verify token " + token);