migrate sdnr features to sulfur
[ccsdk/features.git] / sdnr / wt / oauth-provider / provider-jar / src / main / java / org / onap / ccsdk / features / sdnr / wt / oauthprovider / OAuth2Realm.java
1 /*
2  * ============LICENSE_START=======================================================
3  * ONAP : ccsdk features
4  * ================================================================================
5  * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property.
6  * All rights reserved.
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
11  *
12  *     http://www.apache.org/licenses/LICENSE-2.0
13  *
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=========================================================
20  *
21  */
22 package org.onap.ccsdk.features.sdnr.wt.oauthprovider;
23
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;
42
43 public class OAuth2Realm extends TokenAuthRealm {
44
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;
49
50     public OAuth2Realm() throws IllegalArgumentException, IOException, InvalidConfigurationException {
51         super();
52         super.setName(REALM_NAME);
53         this.config = Config.getInstance();
54         this.tokenCreator = TokenCreator.getInstance(this.config);
55         LOG.info("instantiated");
56     }
57
58     @Override
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);
63         return supports;
64     }
65
66     @Override
67     public String getName() {
68         return REALM_NAME;
69     }
70
71     @Override
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");
78             }
79         } else if (this.config.doSupportOdlUsers() && (atoken instanceof UsernamePasswordToken)) {
80             //nothing to do
81         } else {
82             throw new AuthenticationException("AuthenticationInfo is not an OAuth2AuthenticationInfo");
83         }
84     }
85
86
87     // check what I can do
88     @Override
89     protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg) {
90
91         LOG.debug("auth info in shiro");
92         Object principal = arg.getPrimaryPrincipal();
93         if (principal instanceof DecodedJWT) {
94             LOG.debug("detected jwt token");
95             try {
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);
102                 }
103                 return authorizationInfo;
104             } catch (ClassCastException e) {
105                 LOG.error("Couldn't decode authorization request", e);
106             }
107         } else if (principal instanceof ODLPrincipal) {
108             LOG.debug("detected basic token");
109             ODLPrincipal odlPrincipal = (ODLPrincipal) principal;
110             return new SimpleAuthorizationInfo(odlPrincipal.getRoles());
111         }
112         return new SimpleAuthorizationInfo();
113     }
114
115
116
117     // check who I am
118     @Override
119     protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
120
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;
128
129             DecodedJWT jwt = this.tokenCreator.verify(oauthToken.getToken());
130             if (jwt != null) {
131                 SimpleAuthenticationInfo authenticationInfo =
132                         new SimpleAuthenticationInfo(jwt, token.getCredentials(), getName());
133                 return authenticationInfo;
134
135             }
136         } else {
137             LOG.debug("no valid token found");
138         }
139         throw new AuthenticationException("unable to verify token " + token);
140
141     }
142
143 }