shiro-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Stanisław Barański (JIRA) <j...@apache.org>
Subject [jira] [Updated] (SHIRO-647) SubjectBuilder doesn't fill principals when principals and sessionId is specified
Date Sat, 19 May 2018 07:59:00 GMT

     [ https://issues.apache.org/jira/browse/SHIRO-647?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]

Stanisław Barański updated SHIRO-647:
-------------------------------------
    Description: 
Hello. 
I'm trying to implement one role at a time scenario. 

It this case first I'm signing user with 
{code:java}
//Kotlin
val token = UsernamePasswordToken(credentials.name, credentials.password) 
SecurityUtils.getSubject().login(token) {code}
then, when the user select role I create session: 
{code:java}
val sessionId = SecurityUtils.getSubject().session.id as String 
val mySession = MySession(sessionId, selectedRoleId) {code}
then when the user wants to execute request I restore Subject from this sessionId 
{code:java}
val subject = Subject.Builder() 
       .sessionId(mySession.sessionId) 
       .buildSubject() {code}
and everything goes fine, in the doGetAuthorizationInfo method I'm able to identify the Subject
from principalCollection since there is his id (eg. 2). 
{code:java}
fun doGetAuthorizationInfo(principals: PrincipalCollection) { 
    val subjectId : Long = principals.fromRealm(name).iterator().next() as Long 
    ... {code}
but the problem is when I want to be aware of selected role in the doGetAuthorizationInfo
method. I tried to pass another principal with selected roleId but 
{code:java}
val rolePrincipal = RolePrincipal(mySession.roleId) 
val principals = SimplePrincipalCollection(listOf(rolePrincipal, mySession.id), realm.name) 

val subject = Subject.Builder() 
      .principals(principals) 
      .sessionId(mySession.id) 
      .buildSubject() {code}
then the session is not being resolved and in the doGetAuthorizationInfo method, I'm only
getting raw mySession.id(eg. "36fa4f4a-d55e-47df-8170-13bcdf6f2aa6") instead of mine subjectId(eg.
2). 

In other words 
               
{noformat}
 .principals(principals) {noformat}
and 
               
{noformat}
 .sessionId(mySession.id) {noformat}
seems to not work together, the .principals is blocking .sessionId from being resolved to
subjectId. 

 

 

EDIT:

It's not elegant but I found workaround:

 

 
{code:java}
val subject = Subject.Builder()
        .sessionId(mySession.id)
        .buildSubject()

// Recreate Subject with additional rolePrincipal
val rolePrincipal = RolePrincipal(mySession.roleId)
val principals = listOf(subject.principal, rolePrincipal)

val subjectContext = DefaultSubjectContext()
subjectContext.session = subject.session
subjectContext.isAuthenticated = subject.isAuthenticated
subjectContext.principals = SimplePrincipalCollection(principals, realm.name)
val subjectRecreated = DefaultSubjectFactory().createSubject(subjectContext)

if (!subjectRecreated.isAuthenticated)
    throw AuthorizationException("Restored session is not authenticated")

subjectRecreated.checkPermission("user:read:*")
{code}
 

 and then in my doGethAuthorizationInfo I'm easly getting both subjectId and selected roleId

 
{code:java}
override fun doGetAuthorizationInfo(principals: PrincipalCollection){
    var subjectId: Long = -1L
    var roleId: Long = -1L

    for (principal in principals.fromRealm(name).iterator())
        when (principal) {
            is Long -> subjectId = principal
            is RolePrincipal -> roleId = principal.roleId
        }{code}
But I'm sure there is better approach to do so.

 

  was:
Hello. 
I'm trying to implement one role at a time scenario. 

It this case first I'm signing user with 


{code:java}
                val token = UsernamePasswordToken(credentials.name, credentials.password) 
                SecurityUtils.getSubject().login(token) {code}


then, when the user select role I create session: 


{code:java}
                val sessionId = SecurityUtils.getSubject().session.id as String 
                val mySession = MySession(sessionId, selectedRoleId) {code}


then when the user wants to execute request I restore Subject from this sessionId 


{code:java}
                val subject = Subject.Builder() 
                        .sessionId(mySession.sessionId) 
                        .buildSubject() {code}


and everything goes fine, in the doGetAuthorizationInfo method I'm able to identify the Subject
from principalCollection since there is his id (eg. 2). 


{code:java}
fun doGetAuthorizationInfo(principals: PrincipalCollection) { 
    val subjectId : Long = principals.fromRealm(name).iterator().next() as Long 
    ... {code}

but the problem is when I want to be aware of selected role in the doGetAuthorizationInfo
method. I tried to pass another principal with selected roleId but 


{code:java}
val rolePrincipal = RolePrincipal(mySession.roleId) 
val principals = SimplePrincipalCollection(listOf(rolePrincipal, mySession.id), realm.name) 

val subject = Subject.Builder() 
                     .principals(principals) 
                     .sessionId(mySession.id) 
                        .buildSubject() {code}

then the session is not being resolved and in the doGetAuthorizationInfo method, I'm only
getting raw mySession.id(eg. "36fa4f4a-d55e-47df-8170-13bcdf6f2aa6") instead of mine subjectId(eg.
2). 

In other words 
               
{noformat}
 .principals(principals) {noformat}

and 
               
{noformat}
 .sessionId(mySession.id) {noformat}


seems to not work together, the .principals is blocking .sessionId from being resolved to
subjectId. 

 


> SubjectBuilder doesn't fill principals when principals and sessionId is specified
> ---------------------------------------------------------------------------------
>
>                 Key: SHIRO-647
>                 URL: https://issues.apache.org/jira/browse/SHIRO-647
>             Project: Shiro
>          Issue Type: Bug
>          Components: Authentication (log-in)
>    Affects Versions: 1.3.2
>            Reporter: Stanisław Barański
>            Priority: Minor
>
> Hello. 
> I'm trying to implement one role at a time scenario. 
> It this case first I'm signing user with 
> {code:java}
> //Kotlin
> val token = UsernamePasswordToken(credentials.name, credentials.password) 
> SecurityUtils.getSubject().login(token) {code}
> then, when the user select role I create session: 
> {code:java}
> val sessionId = SecurityUtils.getSubject().session.id as String 
> val mySession = MySession(sessionId, selectedRoleId) {code}
> then when the user wants to execute request I restore Subject from this sessionId 
> {code:java}
> val subject = Subject.Builder() 
>        .sessionId(mySession.sessionId) 
>        .buildSubject() {code}
> and everything goes fine, in the doGetAuthorizationInfo method I'm able to identify the
Subject from principalCollection since there is his id (eg. 2). 
> {code:java}
> fun doGetAuthorizationInfo(principals: PrincipalCollection) { 
>     val subjectId : Long = principals.fromRealm(name).iterator().next() as Long 
>     ... {code}
> but the problem is when I want to be aware of selected role in the doGetAuthorizationInfo
method. I tried to pass another principal with selected roleId but 
> {code:java}
> val rolePrincipal = RolePrincipal(mySession.roleId) 
> val principals = SimplePrincipalCollection(listOf(rolePrincipal, mySession.id), realm.name) 
> val subject = Subject.Builder() 
>       .principals(principals) 
>       .sessionId(mySession.id) 
>       .buildSubject() {code}
> then the session is not being resolved and in the doGetAuthorizationInfo method, I'm
only getting raw mySession.id(eg. "36fa4f4a-d55e-47df-8170-13bcdf6f2aa6") instead of mine
subjectId(eg. 2). 
> In other words 
>                
> {noformat}
>  .principals(principals) {noformat}
> and 
>                
> {noformat}
>  .sessionId(mySession.id) {noformat}
> seems to not work together, the .principals is blocking .sessionId from being resolved
to subjectId. 
>  
>  
> EDIT:
> It's not elegant but I found workaround:
>  
>  
> {code:java}
> val subject = Subject.Builder()
>         .sessionId(mySession.id)
>         .buildSubject()
> // Recreate Subject with additional rolePrincipal
> val rolePrincipal = RolePrincipal(mySession.roleId)
> val principals = listOf(subject.principal, rolePrincipal)
> val subjectContext = DefaultSubjectContext()
> subjectContext.session = subject.session
> subjectContext.isAuthenticated = subject.isAuthenticated
> subjectContext.principals = SimplePrincipalCollection(principals, realm.name)
> val subjectRecreated = DefaultSubjectFactory().createSubject(subjectContext)
> if (!subjectRecreated.isAuthenticated)
>     throw AuthorizationException("Restored session is not authenticated")
> subjectRecreated.checkPermission("user:read:*")
> {code}
>  
>  and then in my doGethAuthorizationInfo I'm easly getting both subjectId and selected
roleId
>  
> {code:java}
> override fun doGetAuthorizationInfo(principals: PrincipalCollection){
>     var subjectId: Long = -1L
>     var roleId: Long = -1L
>     for (principal in principals.fromRealm(name).iterator())
>         when (principal) {
>             is Long -> subjectId = principal
>             is RolePrincipal -> roleId = principal.roleId
>         }{code}
> But I'm sure there is better approach to do so.
>  



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

Mime
View raw message