aboutsummaryrefslogtreecommitdiffstats
path: root/sdnr/wt/oauth-provider/oauth-core/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/OAuth2Realm.java
blob: b9f3d6119f96a68998806b4f62bdd7ac5b5938ba (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
/*
 * ============LICENSE_START=======================================================
 * ONAP : ccsdk features
 * ================================================================================
 * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property.
 * All rights reserved.
 * ================================================================================
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ============LICENSE_END=========================================================
 *
 */
package org.onap.ccsdk.features.sdnr.wt.oauthprovider;

import com.auth0.jwt.interfaces.DecodedJWT;
import java.io.IOException;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.subject.PrincipalCollection;
import org.onap.ccsdk.features.sdnr.wt.oauthprovider.data.Config;
import org.onap.ccsdk.features.sdnr.wt.oauthprovider.data.InvalidConfigurationException;
import org.onap.ccsdk.features.sdnr.wt.oauthprovider.providers.TokenCreator;
import org.opendaylight.aaa.api.shiro.principal.ODLPrincipal;
import org.apache.shiro.authc.BearerToken;
import org.opendaylight.aaa.shiro.realm.TokenAuthRealm;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class OAuth2Realm extends TokenAuthRealm {

    public static final String REALM_NAME = "OAuth2Realm";
    private static final Logger LOG = LoggerFactory.getLogger(OAuth2Realm.class);
    private final TokenCreator tokenCreator;
    private final Config config;

    public OAuth2Realm() throws IllegalArgumentException, IOException, InvalidConfigurationException {
        super();
        super.setName(REALM_NAME);
        this.config = Config.getInstance();
        this.tokenCreator = TokenCreator.getInstance(this.config);
        LOG.info("instantiated");
    }

    @Override
    public boolean supports(AuthenticationToken token) {
        boolean supports = (token instanceof BearerToken)
                || (this.config.doSupportOdlUsers() && (token instanceof UsernamePasswordToken));
        LOG.debug("supports {} is {}", token == null ? null : token.getClass().getName(), supports);
        return supports;
    }

    @Override
    public String getName() {
        return REALM_NAME;
    }

    @Override
    protected void assertCredentialsMatch(AuthenticationToken atoken, AuthenticationInfo ai)
            throws AuthenticationException {
        LOG.debug("assertCredentialsMatch");
        if (atoken instanceof BearerToken) {
            if (this.tokenCreator.verify(((BearerToken) atoken).getToken()) == null) {
                throw new AuthenticationException("Credentials do not match");
            }
        } else if (this.config.doSupportOdlUsers() && (atoken instanceof UsernamePasswordToken)) {
            //nothing to do
        } else {
            throw new AuthenticationException("AuthenticationInfo is not an OAuth2AuthenticationInfo");
        }
    }


    // check what I can do
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg) {

        LOG.debug("auth info in shiro");
        Object principal = arg.getPrimaryPrincipal();
        if (principal instanceof DecodedJWT) {
            LOG.debug("detected jwt token");
            try {
                DecodedJWT token = (DecodedJWT) arg.getPrimaryPrincipal();
                String[] roles = token.getClaim("roles").asArray(String.class);
                SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
                for (String role : roles) {
                    LOG.trace("found role {} in token", role);
                    authorizationInfo.addRole(role);
                }
                return authorizationInfo;
            } catch (ClassCastException e) {
                LOG.error("Couldn't decode authorization request", e);
            }
        } else if (principal instanceof ODLPrincipal) {
            LOG.debug("detected basic token");
            ODLPrincipal odlPrincipal = (ODLPrincipal) principal;
            return new SimpleAuthorizationInfo(odlPrincipal.getRoles());
        }
        return new SimpleAuthorizationInfo();
    }



    // check who I am
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

        LOG.debug("auth token in shiro:");
        if (token instanceof UsernamePasswordToken && this.config.doSupportOdlUsers()) {
            LOG.debug("basic auth token found");
            return super.doGetAuthenticationInfo(token);
        } else if (token instanceof BearerToken) {
            LOG.debug("jwt token found");
            BearerToken oauthToken = (BearerToken) token;

            DecodedJWT jwt = this.tokenCreator.verify(oauthToken.getToken());
            if (jwt != null) {
                SimpleAuthenticationInfo authenticationInfo =
                        new SimpleAuthenticationInfo(jwt, token.getCredentials(), getName());
                return authenticationInfo;

            }
        } else {
            LOG.debug("no valid token found");
        }
        throw new AuthenticationException("unable to verify token " + token);

    }

}