Hi,
I have run into a possible issue with regards to using the Subject
login(use,pwd) api when the SecurityUtils SecurityManager has not been set
(SecurityUtils.setSecurityManager(secMgr). I have proposed a possible
change but I would appreciate your advice.
The following code:
Subject currentUser =
newSubject.Builder(securityManager).buildSubject();
UsernamePasswordToken token = new UsernamePasswordToken(userName,
password);
currentUser.login(token);
Results in an exception (this exception is not the end of the world as
later in the code the current default security manager will get set so all
should be ok):
15:31:01.325 [main] DEBUG o.a.s.s.s.DefaultSubjectContext - No
SecurityManager available via SecurityUtils. Heuristics exhausted.
org.apache.shiro.UnavailableSecurityManagerException: No SecurityManager
accessible to the calling code, either bound to the
org.apache.shiro.util.ThreadContext or as a vm static singleton. This is
an invalid application configuration.
at
org.apache.shiro.SecurityUtils.getSecurityManager(SecurityUtils.java:123)
~[shiro-core-1.2.1.jar:1.2.1]
at
org.apache.shiro.subject.support.DefaultSubjectContext.resolveSecurityManager(DefaultSubjectContext.java:106)
~[shiro-core-1.2.1.jar:1.2.1]
at
org.apache.shiro.mgt.DefaultSecurityManager.ensureSecurityManager(DefaultSecurityManager.java:411)
[shiro-core-1.2.1.jar:1.2.1]
at
org.apache.shiro.mgt.DefaultSecurityManager.createSubject(DefaultSecurityManager.java:333)
[shiro-core-1.2.1.jar:1.2.1]
at
org.apache.shiro.mgt.DefaultSecurityManager.createSubject(DefaultSecurityManager.java:183)
[shiro-core-1.2.1.jar:1.2.1]
at
org.apache.shiro.mgt.DefaultSecurityManager.login(DefaultSecurityManager.java:283)
[shiro-core-1.2.1.jar:1.2.1]
at
org.apache.shiro.subject.support.DelegatingSubject.login(DelegatingSubject.java:256)
[shiro-core-1.2.1.jar:1.2.1]
I think the issue rises from line 1 of the following code in
DefaultSecurityManager:
protected Subject createSubject(AuthenticationToken token,
AuthenticationInfo info, Subject existing) {
SubjectContext context = createSubjectContext(); *<-- Results in a
context with no security manager*
context.setAuthenticated(true);
context.setAuthenticationToken(token);
context.setAuthenticationInfo(info);
if (existing != null) {
context.setSubject(existing);
}
return createSubject(context); *<-- This complains about no
security manager*
}
Could the DefaultSecurityManager code instead be as follows?
protected Subject createSubject(AuthenticationToken token,
AuthenticationInfo info, Subject existing) {
SubjectContext context = createSubjectContext();
context.setAuthenticated(true);
context.setAuthenticationToken(token);
context.setAuthenticationInfo(info);
if (existing != null) {
context.setSubject(existing);
context.setSecurityManager(this); *<-- Set the security manager
before the createSubject*
}
return createSubject(context);
}
I could mask this debug message/exception but before I do that it would be
good to know (based on your experience) if not setting the VM static
security manager will result in any other issues.
I basically create a Subject in one of two ways:
(1) For Login -> new Subject.Builder(securityManager).buildSubject(); …
subject.login(..)
(2) For existing session -> new
Subject.Builder(mSecurityManager).sessionId(sessionId).buildSubject(); ...
Cheers,
Stuart