Problems With Declarative Security With A Custom Login Module (Doc ID 1954552.1)

Last updated on MAY 24, 2017

Applies to:

Oracle WebLogic Server - Version 12.1.3.0.0 and later
Information in this document applies to any platform.

Symptoms

When it's checked the caller roles via SessionContext within an EJB, everything works fine. The CallerPrincipal are set well and the isCallerInRole() returns what is expected. But when declared, some EJB with @DeclareRoles() or @RolesAllowed(), the getCallerPrincipal() still return the right value but the isCallerInRole()-Method always return false. It doesnt matter what EJB is declared.

DeclarativeSecurity

-----------------------------

package org.ora.security;

import javax.annotation.Resource;
import javax.annotation.security.DeclareRoles;
import javax.ejb.SessionContext;
import javax.ejb.Stateless;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path("declarativesecurity")
@Produces(MediaType.APPLICATION_JSON)
@Stateless
//@DeclareRoles("role1")
public class HelloDeclarativeSecurityResource {

    @Resource
    private SessionContext sessionContext;

    @GET
    @Path("/hello")
    public String getHello() {
        System.out.println("callerPrincipal: " + sessionContext.getCallerPrincipal());
        System.out.println("isCallerInRole(role1): " + sessionContext.isCallerInRole("role1"));
        return "hello";
    }
}

--------------

=======================
package org.ora.security;

import java.util.Arrays;
import java.util.HashSet;

import org.ora.security.DecodedToken;
import org.ora.security.TokenDecoder;
import org.ora.security.TokenLoginModule;

public abstract class MyWeblogicSecurityLoginModule extends TokenLoginModule {

    @Override
    protected TokenDecoder fetchTokenDecoder() {
        return new TokenDecoder() {

            @Override
            public DecodedToken decode(String token) {
                String[] split = token.split(";");
                return new DecodedToken(split[0], new HashSet<String>(Arrays.asList(split)));
            }
        };
    }

}
======================
package org.ora.security;

import java.util.Set;

public class DecodedToken
{
  private String user;
  private Set<String> roles;
 
  public DecodedToken(String user, Set<String> roles)
  {
    this.user = user;
    this.roles = roles;
  }
 
  public String getUser()
  {
    return this.user;
  }
 
  public Set<String> getRoles()
  {
    return this.roles;
  }
}
======================
package org.ora.security;

public abstract interface TokenDecoder
{
  public abstract DecodedToken decode(String paramString);
}
======================
web.xml
-----------
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-

instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-

app_3_0.xsd"
    version="3.0">

    <display-name>DeclarativeSecurity</display-name>
    <servlet>
    <servlet-name>RestServlet</servlet-name>
    <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
    <init-param>
      <param-name>jersey.config.server.provider.packages</param-name>
      <param-value>org.ora.security</param-value>
    </init-param>
  </servlet>
  <servlet-mapping>
    <servlet-name>RestServlet</servlet-name>
    <url-pattern>/*</url-pattern>
  </servlet-mapping>
  <security-constraint>
    <web-resource-collection>
      <web-resource-name>All Access</web-resource-name>
      <url-pattern>/*</url-pattern>
      <http-method>DELETE</http-method>
      <http-method>PUT</http-method>
      <http-method>HEAD</http-method>
      <http-method>OPTIONS</http-method>
      <http-method>TRACE</http-method>
      <http-method>GET</http-method>
      <http-method>POST</http-method>
    </web-resource-collection>
    <user-data-constraint>
      <transport-guarantee>NONE</transport-guarantee>
    </user-data-constraint>
  </security-constraint>
  <security-role>
    <role-name>role1</role-name>
  </security-role>
</web-app>

Steps:
------------
- Set the following Java-Options in your weblogic start script (-Dwaspsrvfw.security.loginmodule=

MyWeblogicSecurityLoginModule -Dwaspsrvfw.security.token.header.key=SecurityAssertion)
- Do the following configurations with the weblogic console:
 - add group "role1"
 - add global role "role1"
 - set in "role1" as restriction the group "role1" (associate role1 with group role1)
- start weblogic and deploy the project
- call the REST-Service with the following URL:

http://localhost:7001/HelloDeclarativeSecurity/declarativesecurity/hello
 Important: Set the following HTTP-Header "SecurityAssertion: user1;role1"
- Now everything should be fine. On system out you should see the following output:

 callerPrincipal: user1
 isCallerInRole(role1): true

- Now add the annotation @DeclareRoles("role1") to the class HelloDeclarativeSecurityResource,

deploy again and do the same HTTP-Request. Now you should see the following output on system out:

 callerPrincipal: user1
 isCallerInRole(role1): false

 Error: It's expected "true" here .

Cause

Sign In with your My Oracle Support account

Don't have a My Oracle Support account? Click to get started

My Oracle Support provides customers with access to over a
Million Knowledge Articles and hundreds of Community platforms