package org.onap.ccsdk.features.sdnr.wt.oauthprovider.http;
import com.fasterxml.jackson.databind.ObjectMapper;
+import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import org.apache.shiro.codec.Base64;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
-import org.jolokia.osgi.security.Authenticator;
-import org.onap.ccsdk.features.sdnr.wt.common.http.BaseHTTPClient;
-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.data.NoDefinitionFoundException;
-import org.onap.ccsdk.features.sdnr.wt.oauthprovider.data.OAuthProviderConfig;
-import org.onap.ccsdk.features.sdnr.wt.oauthprovider.data.OAuthToken;
-import org.onap.ccsdk.features.sdnr.wt.oauthprovider.data.OdlPolicy;
-import org.onap.ccsdk.features.sdnr.wt.oauthprovider.data.UnableToConfigureOAuthService;
-import org.onap.ccsdk.features.sdnr.wt.oauthprovider.data.UserTokenPayload;
+import org.onap.ccsdk.features.sdnr.wt.oauthprovider.data.*;
+import org.onap.ccsdk.features.sdnr.wt.oauthprovider.data.OdlShiroConfiguration.MainItem;
+import org.onap.ccsdk.features.sdnr.wt.oauthprovider.data.OdlShiroConfiguration.UrlItem;
+import org.onap.ccsdk.features.sdnr.wt.oauthprovider.filters.CustomizedMDSALDynamicAuthorizationFilter;
import org.onap.ccsdk.features.sdnr.wt.oauthprovider.providers.AuthService;
import org.onap.ccsdk.features.sdnr.wt.oauthprovider.providers.AuthService.PublicOAuthProviderConfig;
import org.onap.ccsdk.features.sdnr.wt.oauthprovider.providers.MdSalAuthorizationStore;
import org.onap.ccsdk.features.sdnr.wt.oauthprovider.providers.OAuthProviderFactory;
import org.onap.ccsdk.features.sdnr.wt.oauthprovider.providers.TokenCreator;
-import org.opendaylight.aaa.api.IdMService;
+import org.opendaylight.aaa.api.AuthenticationException;
+import org.opendaylight.aaa.api.Claim;
+import org.opendaylight.aaa.api.PasswordCredentialAuth;
+import org.opendaylight.aaa.api.PasswordCredentials;
+import org.opendaylight.aaa.tokenauthrealm.auth.PasswordCredentialBuilder;
import org.opendaylight.mdsal.binding.api.DataBroker;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.aaa.app.config.rev170619.ShiroConfiguration;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.aaa.app.config.rev170619.shiro.ini.Main;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.aaa.app.config.rev170619.shiro.ini.Urls;
+import org.osgi.service.http.HttpService;
+import org.osgi.service.http.NamespaceException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private static final Logger LOG = LoggerFactory.getLogger(AuthHttpServlet.class.getName());
private static final long serialVersionUID = 1L;
- public static final String BASEURI = "/oauth";
+ private static final String BASEURI = "/oauth";
private static final String LOGINURI = BASEURI + "/login";
private static final String LOGOUTURI = BASEURI + "/logout";
private static final String PROVIDERSURI = BASEURI + "/providers";
private static final String CLASSNAME_ODLMDSALAUTH =
"org.opendaylight.aaa.shiro.realm.MDSALDynamicAuthorizationFilter";
public static final String LOGIN_REDIRECT_FORMAT = LOGINURI + "/%s";
+ private static final String URI_PRE = BASEURI;
+ private static final String CONFIGFILE ="/opt/opendaylight/etc/opendaylight/datastore/initial/config/aaa-app-config.xml";
private final ObjectMapper mapper;
/* state <=> AuthProviderService> */
private final Map<String, AuthService> providerStore;
private final TokenCreator tokenCreator;
private final Config config;
- private static Authenticator odlAuthenticator;
- private static IdMService odlIdentityService;
- private static ShiroConfiguration shiroConfiguration;
private static MdSalAuthorizationStore mdsalAuthStore;
+ private PasswordCredentialAuth passwordCredentialAuth;
+ private OdlShiroConfiguration shiroConfiguration;
public AuthHttpServlet() throws IllegalArgumentException, IOException, InvalidConfigurationException,
UnableToConfigureOAuthService {
+ this(CONFIGFILE);
+ }
+ public AuthHttpServlet(String shiroconfigfile) throws IllegalArgumentException, IOException, InvalidConfigurationException,
+ UnableToConfigureOAuthService {
this.config = Config.getInstance();
+ this.shiroConfiguration = loadShiroConfig(shiroconfigfile);
this.tokenCreator = TokenCreator.getInstance(this.config);
this.mapper = new ObjectMapper();
this.providerStore = new HashMap<>();
}
}
- public void setOdlAuthenticator(Authenticator odlAuthenticator2) {
- odlAuthenticator = odlAuthenticator2;
+ public void setDataBroker(DataBroker dataBroker) {
+ CustomizedMDSALDynamicAuthorizationFilter.setDataBroker(dataBroker);
+ mdsalAuthStore = new MdSalAuthorizationStore(dataBroker);
}
- public void setOdlIdentityService(IdMService odlIdentityService2) {
- odlIdentityService = odlIdentityService2;
+ public void setPasswordCredentialAuth(PasswordCredentialAuth passwordCredentialAuth) {
+ this.passwordCredentialAuth = passwordCredentialAuth;
}
- public void setShiroConfiguration(ShiroConfiguration shiroConfiguration2) {
- shiroConfiguration = shiroConfiguration2;
+
+ public void onUnbindService(HttpService httpService) {
+ httpService.unregister(AuthHttpServlet.URI_PRE);
+
}
- public void setDataBroker(DataBroker dataBroker) {
- mdsalAuthStore = new MdSalAuthorizationStore(dataBroker);
+ public void onBindService(HttpService httpService)
+ throws ServletException, NamespaceException {
+ if (httpService == null) {
+ LOG.warn("Unable to inject HttpService into loader.");
+ } else {
+ httpService.registerServlet(AuthHttpServlet.URI_PRE, this, null, null);
+ LOG.info("oauth servlet registered.");
+ }
+ }
+ private static OdlShiroConfiguration loadShiroConfig(String filename) throws IOException {
+ OdlXmlMapper mapper = new OdlXmlMapper();
+ return mapper.readValue(new File(filename), OdlShiroConfiguration.class);
}
@Override
if (redirectUrl == null) {
redirectUrl = this.config.getPublicUrl();
}
- // if nothing configured and nothing from request
- if(redirectUrl == null || redirectUrl.isBlank()){
- redirectUrl="/";
- }
UserTokenPayload userInfo = this.tokenCreator.decode(bearerToken);
if (bearerToken != null && userInfo != null && !userInfo.isInternal()) {
AuthService provider = this.providerStore.getOrDefault(userInfo.getProviderId(), null);
/**
* find out what urls can be accessed by user and which are forbidden
- *
+ * <p>
* urlEntries: "anon" -> any access allowed "authcXXX" -> no grouping rule -> any access for user allowed "authcXXX,
* roles[abc] -> user needs to have role abc "authcXXX, roles["abc,def"] -> user needs to have roles abc AND def
* "authcXXX, anyroles[abc] -> user needs to have role abc "authcXXX, anyroles["abc,def"] -> user needs to have
* roles abc OR def
*
- *
* @param req
* @return
*/
private List<OdlPolicy> getPoliciesForUser(HttpServletRequest req) {
- List<Urls> urlRules = shiroConfiguration.getUrls();
- UserTokenPayload data = this.getUserInfo(req);
List<OdlPolicy> policies = new ArrayList<>();
+ List<UrlItem> urlRules = this.shiroConfiguration.getUrls();
+ UserTokenPayload data = this.getUserInfo(req);
if (urlRules != null) {
LOG.debug("try to find rules for user {} with roles {}",
data == null ? "null" : data.getPreferredUsername(), data == null ? "null" : data.getRoles());
final String regex = "^([^,]+)[,]?[\\ ]?([anyroles]+)?(\\[\"?([a-zA-Z,]+)\"?\\])?";
final Pattern pattern = Pattern.compile(regex);
Matcher matcher;
- for (Urls urlRule : urlRules) {
+ for (UrlItem urlRule : urlRules) {
matcher = pattern.matcher(urlRule.getPairValue());
if (matcher.find()) {
try {
//anon access allowed
if (authClass == null) {
policy = Optional.of(OdlPolicy.allowAll(urlRule.getPairKey()));
- } else if (authClass.equals(CLASSNAME_ODLBASICAUTH)) {
+ } else if (authClass.equals(CLASSNAME_ODLBASICAUTH) || "authcBasic".equals(urlRule.getPairKey())) {
policy = isBasic(req) ? this.getTokenBasedPolicy(urlRule, matcher, data)
: Optional.of(OdlPolicy.denyAll(urlRule.getPairKey()));
} else if (authClass.equals(CLASSNAME_ODLBEARERANDBASICAUTH)) {
* @param data
* @return
*/
- private Optional<OdlPolicy> getMdSalBasedPolicy(Urls urlRule, UserTokenPayload data) {
+ private Optional<OdlPolicy> getMdSalBasedPolicy(UrlItem urlRule, UserTokenPayload data) {
if (mdsalAuthStore != null) {
return data != null ? mdsalAuthStore.getPolicy(urlRule.getPairKey(), data.getRoles())
: Optional.of(OdlPolicy.denyAll(urlRule.getPairKey()));
* @param data
* @return
*/
- private Optional<OdlPolicy> getTokenBasedPolicy(Urls urlRule, Matcher matcher, UserTokenPayload data) {
+ private Optional<OdlPolicy> getTokenBasedPolicy(UrlItem urlRule, Matcher matcher,
+ UserTokenPayload data) {
final String url = urlRule.getPairKey();
final String rule = urlRule.getPairValue();
if (!rule.contains(",")) {
if ("anon".equals(key)) {
return null;
}
- List<Main> list = shiroConfiguration.getMain();
- Optional<Main> main =
+ if("authcBasic".equals(key)){
+ return CLASSNAME_ODLBASICAUTH;
+ }
+ List<MainItem> list = shiroConfiguration.getMain();
+ Optional<MainItem> main =
list == null ? Optional.empty() : list.stream().filter(e -> e.getPairKey().equals(key)).findFirst();
if (main.isPresent()) {
return main.get().getPairValue();
if (!username.contains("@")) {
username = String.format("%s@%s", username, domain);
}
- List<String> roles = odlIdentityService.listRoles(username, domain);
+ List<String> roles = List.of();// odlIdentityService.listRoles(username, domain);
return UserTokenPayload.createInternal(username, roles);
}
}
private static boolean isBasic(HttpServletRequest req) {
final String header = req.getHeader(HEAEDER_AUTHORIZATION);
- return header == null ? false : header.startsWith("Basic");
+ return header != null && header.startsWith("Basic");
}
private static boolean isBearer(HttpServletRequest req) {
final String header = req.getHeader(HEAEDER_AUTHORIZATION);
- return header == null ? false : header.startsWith("Bearer");
+ return header != null && header.startsWith("Bearer");
}
private boolean rolesMatch(List<String> userRoles, List<String> policyRoles, boolean any) {
hostUrl = matcher.group(1);
}
}
- LOG.debug("host={}", hostUrl);
+ LOG.info("host={}", hostUrl);
return hostUrl;
}
}
}
- resp.sendError(HttpServletResponse.SC_NOT_FOUND);
+ resp.sendError(HttpServletResponse.SC_BAD_REQUEST);
}
private BearerToken doLogin(String username, String password, String domain) {
- if (!username.contains("@")) {
- username = String.format("%s@%s", username, domain);
+
+ PasswordCredentials pc =
+ (new PasswordCredentialBuilder()).setUserName(username).setPassword(password).setDomain(domain).build();
+ Claim claim = null;
+ try {
+ claim = this.passwordCredentialAuth.authenticate(pc);
+ } catch (AuthenticationException e) {
+ LOG.warn("unable to authentication user {} for domain {}: ", username, domain, e);
}
- HttpServletRequest req = new HeadersOnlyHttpServletRequest(
- Map.of("Authorization", BaseHTTPClient.getAuthorizationHeaderValue(username, password)));
- if (odlAuthenticator.authenticate(req)) {
- List<String> roles = odlIdentityService.listRoles(username, domain);
+ if (claim != null) {
+ List<String> roles = claim.roles().stream().toList();//odlIdentityService.listRoles(username, domain);
UserTokenPayload data = new UserTokenPayload();
data.setPreferredUsername(username);
data.setFamilyName("");
data.setExp(this.tokenCreator.getDefaultExp());
data.setRoles(roles);
return this.tokenCreator.createNewJWT(data);
-
+ } else {
+ LOG.info("unable to read auth from authservice");
}
return null;
}
- private void sendResponse(HttpServletResponse resp, int code) throws IOException {
+/* private void sendResponse(HttpServletResponse resp, int code) throws IOException {
this.sendResponse(resp, code, null);
- }
+ }*/
private void sendResponse(HttpServletResponse resp, int code, Object data) throws IOException {
byte[] output = data != null ? mapper.writeValueAsString(data).getBytes() : new byte[0];
resp.setStatus(code);
resp.setContentLength(output.length);
resp.setContentType("application/json");
- ServletOutputStream os = null;
- os = resp.getOutputStream();
+ ServletOutputStream os = resp.getOutputStream();
os.write(output);
}
private void logout() {
- final Subject subject = SecurityUtils.getSubject();
+ /* final Subject subject = SecurityUtils.getSubject();
try {
subject.logout();
Session session = subject.getSession(false);
}
} catch (ShiroException e) {
LOG.debug("Couldn't log out {}", subject, e);
- }
+ }*/
}
}