[
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)