Shiro Logout - org.apache.shiro.session.UnknownSessionException - shiro

I have currently an issue with Apache Shiro for logout:
Here my Shiro.ini
[main]
#### Session
sessionIdCookie=org.apache.shiro.web.servlet.SimpleCookie
#sessionIdCookie.path = /
sessionIdCookie.httpOnly = true
sessionIdCookie.name = sid
sessionIdCookie.domain = localhost
sessionIdCookie.maxAge=28800000
sessionIdCookie.secure = true
sessionIdCookie.sameSite = NONE
sessionManager=org.apache.shiro.web.session.mgt.DefaultWebSessionManager
sessionManager.sessionIdCookie=$sessionIdCookie
sessionManager.sessionIdCookieEnabled=true
securityManager.sessionManager=$sessionManager
# Session Timeout nach 8 Stunden
sessionManager.globalSessionTimeout= 28800000
sessionListener1= de.dpunkt.myaktion.util.MySessionListener1
sessionManager.sessionListeners=$sessionListener1
# Session validation = 5 minutes
sessionManager.sessionValidationInterval = 300000
#sessionManager = org.apache.shiro.web.session.mgt.DefaultWebSessionManager
#securityManager.sessionMode=native
sessionValidationScheduler=org.apache.shiro.session.mgt.ExecutorServiceSessionValidationScheduler
sessionValidationScheduler.interval = 60000
sessionValidationScheduler.sessionManager=$sessionManager
sessionManager.sessionValidationScheduler=$sessionValidationScheduler
sessionManager.deleteInvalidSessions=true
#sessionFactory=org.apache.shiro.session.mgt.OnlineSessionFactory
#sessionManager.sessionFactory=$sessionFactory
#securityManager.subjectDAO.sessionStorageEvaluator.sessionStorageEnabled = false
# password hashing specification, put something big for hasIterations
sha512Matcher = org.apache.shiro.authc.credential.HashedCredentialsMatcher
sha512Matcher.hashAlgorithmName=SHA-512
sha512Matcher.hashIterations=1
# Configure JDBC realm datasource.
...
# Realm for Token Login
....
# AuthStrategy
authenticator = org.apache.shiro.authc.pam.ModularRealmAuthenticator
authcStrategy = org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategy
authenticator = org.apache.shiro.authc.pam.ModularRealmAuthenticator
securityManager.authenticator = $authenticator
securityManager.authenticator.authenticationStrategy = $authcStrategy
securityManager.realms = $jdbcRealm, $tcRealm
# Caching
cacheManager = org.apache.shiro.cache.MemoryConstrainedCacheManager
securityManager.cacheManager = $cacheManager
# Using default form based security filter org.apache.shiro.web.filter.authc.FormAuthenticationFilter
authc = org.apache.shiro.web.filter.authc.FormAuthenticationFilter
authc.loginUrl = /common/login.jsf
authc.successUrl = /portal/dashboard.jsf
# Redirect to an access denied page if user does not have access rights
#[roles]
#roles.unauthorizedUrl = /common/access-denied.jsf
#perms.unauthorizedUrl = /accessdenied.jsp
## OTHER
/WEB-INF/layout/portal/** = authc
/portal/** = authc
And here is my Controller Class:
#SessionScoped
#Named
public class LoginBean implements Serializable {
private Subject currentUserShiro;
public void logout() {
LOGGER.info("START logout");
try {
FacesContext facesContext = FacesContext.getCurrentInstance();
HttpSession httpSession = (HttpSession) facesContext.getExternalContext().getSession(false);
ServletContext application = httpSession.getServletContext();
// Shiro User
currentUserShiro.logout();
currentUserShiro = null;
FacesContext.getCurrentInstance().getExternalContext().redirect("/common/login.jsf");
}
catch (UnavailableSecurityManagerException e) {
LOGGER.info("UnavailableSecurityManagerException");
}
catch (UnknownSessionException e) {
LOGGER.info("Unknown Session");
}
catch (ExpiredSessionException e) {
LOGGER.info("Session is expired");
}
catch (StoppedSessionException e) {
LOGGER.info("Session stopped");
}
catch (NullPointerException e) {
}
catch (Exception e) {
LOGGER.error(ExceptionUtils.getFullStackTrace(e));
}
LOGGER.info("END logout");
}
After I press the logout button, I´m getting this error message:
org.apache.shiro.session.UnknownSessionException: There is no session with id [32767ef1-b285-4dc3-8
Can anybody help here? Is there anything which I haven´t considered?
It seems the logout is successful and the user is not able to go back and have the same permission, but everytime I´m getting this Exception.

Alright, you called the logout session on a Subject which is not known to Shiro.
To obtain the current subject, please use Subject currentUser = SecurityUtils.getSubject(); -- the same as for the login method where you call `currentUser.login( token );).
Now, with the logout method, you only need to use:
Subject currentUser = SecurityUtils.getSubject();
currentUser.logout();
... plus a try-catch.
That said, see if you can eliminate your instance field private Subject currentUserShiro. It should not be needed (at least in the code you showed us).
Reference:
https://shiro.apache.org/subject.html

Related

Calling External WCF Service (using generated client) from CRM sandboxed plugin OnPremise is failing

How to call HTTPS WCF web service in Plugin, plugin assembly is registered in sandbox mode. I am getting System.Security.SecurityException exception, Can somebody please provide the way to all https web service. My code is below :
BasicHttpBinding myBinding = new BasicHttpBinding();
myBinding.MaxReceivedMessageSize = Int32.MaxValue;
myBinding.Name = “basicHttpBinding”;
if (EndPoint.ToLower().Contains(“https://”))
{
//Throwing exception here – System.Security.SecurityException exception,
ServicePointManager.ServerCertificateValidationCallback += (sendr, cert, chain, sslPolicyErrors) => true;
ServicePointManager.SecurityProtocol = (SecurityProtocolType)768 | (SecurityProtocolType)3072 | (SecurityProtocolType)192;
myBinding.Security.Mode = BasicHttpSecurityMode.Transport;
}
else
{
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
myBinding.Security.Mode = BasicHttpSecurityMode.None;
}
myBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
myBinding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.None;
myBinding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.UserName;
EndpointAddress endPointAddress = new EndpointAddress(EndPoint);
WebIALClient myClient = new WebIALClient(myBinding, endPointAddress)
Since you are in on-premise version, you can register the plugin assembly in non-sandbox mode. ie Isolation mode = none to overcome such errors.
In case you wanted to use sandbox mode, try using WebClient class for invoking WCF service call. Read more
using (WebClient client = new WebClient())
{
byte[] responseBytes = client.DownloadData(webAddress);
string response = Encoding.UTF8.GetString(responseBytes);
tracingService.Trace(response);
// For demonstration purposes, throw an exception so that the response
// is shown in the trace dialog of the Microsoft Dynamics CRM user interface.
throw new InvalidPluginExecutionException("WebClientPlugin completed successfully.");
}
Can you try and also include: using System.Web.Http.Cors;
[EnableCors(origins: "*", headers: "*", methods: "*")]
[Route("api/ConvertUpload/{env}/{id}")]
public string Get(string env, string id)
{
return "hi";
}
You may have to use WebClient as #Arun has mentioned.

Generate SPNEGO Token Failured

I tried to generate the token which can be used as the HTTP header to authenticate to the HDFS WebHDFS URL and Oozie REST API URL.
I referenced the url below to have the below code to generate the Negotiate token.
https://www.ibm.com/support/knowledgecenter/en/SS7JFU_8.5.5/com.ibm.websphere.express.doc/ae/tsec_SPNEGO_token.html
public class TokenCreation {
private static final String SPNEGO_OID = "1.3.6.1.5.5.2";
private static final String KERBEROS_OID = "1.2.840.113554.1.2.2";
public static byte[] genToken(String principal) {
System.setProperty("javax.security.auth.useSubjectCredsOnly", "false");
byte[] spnegoToken = new byte[0];
try {
Oid spnegoMechOid = new Oid(SPNEGO_OID);
Oid krb5MechOid = new Oid(KERBEROS_OID);
GSSCredential clientGssCreds = null;
GSSManager manager = GSSManager.getInstance();
GSSName gssUserName = manager.createName(principal, GSSName.NT_USER_NAME, krb5MechOid);
clientGssCreds = manager.createCredential(gssUserName.canonicalize(krb5MechOid),
GSSCredential.INDEFINITE_LIFETIME,
krb5MechOid,
GSSCredential.INITIATE_ONLY);
clientGssCreds.add(gssUserName,
GSSCredential.INDEFINITE_LIFETIME,
GSSCredential.INDEFINITE_LIFETIME,
spnegoMechOid, GSSCredential.INITIATE_ONLY);
GSSName gssServerName = manager.createName(principal, GSSName.NT_USER_NAME);
GSSContext clientContext = manager.createContext(gssServerName.canonicalize(spnegoMechOid),
spnegoMechOid,
clientGssCreds,
GSSContext.DEFAULT_LIFETIME);
// optional enable GSS credential delegation
clientContext.requestCredDeleg(true);
// create a SPNEGO token for the target server
spnegoToken = clientContext.initSecContext(spnegoToken, 0, spnegoToken.length);
} catch (GSSException e) {
e.printStackTrace();
}
return spnegoToken;
}
But after running the above code, I always got the below prompt:
2019-09-25 14:12:51 760 [INFO] [pool-2-thread-1] c.s.n.c.u.security.KrbUtils - after loginUserFromKeytab............AtoimcUser:HTTP/host1.exmaple.com#EXAMPLE.COM
2019-09-25 14:12:51 760 [INFO] [pool-2-thread-1] c.s.n.app.oozie.OozieAppCaller - ->>>>>>User Name is HTTP/host1.exmaple.com#EXAMPLE.COM
2019-09-25 14:12:51 760 [INFO] [pool-2-thread-1] c.s.n.app.oozie.OozieAppCaller - ->>>>>>Mode is KERBEROS
>>>KinitOptions cache name is /tmp/krb5cc_0
Kerberos username [root]: ^C^C^C
Kerberos password for root:
You can see at the end of the above output log.
The "Kerberos username" is always prompt to ask for username.
Also I have tried to manually run kinit the keytab.
and the above class can generate the token successfully.
But manually run kinit is NOT the way I wanted.
Would you please help it?
Thanks.
Kerberos and SPNEGO support in Java is cumbersome unfortunately.
I've created a small library to simplify some Kerberos use cases: https://github.com/bedrin/kerb4j
You can use it like this to generate SPNEGO token:
SpnegoClient spnegoClient = SpnegoClient.loginWithKeyTab("svc_consumer", "/opt/myapp/consumer.keytab");
URL url = new URL("http://api.provider.acme.com/api/operation1");
SpnegoContext context = spnegoClient.createContext("http://provider.acme.com"); // Will result in HTTP/provider.acme.com SPN
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestProperty("Authorization", context.createTokenAsAuthroizationHeader());

NOAUTH Authentication required when connecting to Redis Sentinel with LettuceConnectionFactory

I am trying to connect to a Redis server using sentinel with password. I got RedisCommandExecutionException: NOAUTH Authentication required when calling redisTemplate.opsForValue().get("key")
Exception in thread "Thread-6" org.springframework.data.redis.RedisConnectionFailureException: Unable to connect to Redis on localhost:6379; nested exception is com.lambdaworks.redis.RedisCommandExecutionException: NOAUTH Authentication required.
at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory.createLettuceConnector(LettuceConnectionFactory.java:544)
at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory.initConnection(LettuceConnectionFactory.java:213)
at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory.getSharedConnection(LettuceConnectionFactory.java:517)
at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory.getConnection(LettuceConnectionFactory.java:189)
This is how I configured the connection factory:
RedisSentinelConfiguration sentinelConfiguration = new RedisSentinelConfiguration().master("mymaster").sentinel("localhost", 26379);
LettuceConnectionFactory lettuceConnectionFactory = new LettuceConnectionFactory(sentinelConfiguration);
lettuceConnectionFactory.setDatabase(1);
lettuceConnectionFactory.setPassword("foobared");
When I tried using JedisConnectionFactory, it works.
It looks like the password is not set when using LettuceConnectionFactory with sentinel.
I'm using spring-data-redis 1.7.2.
UPDATE:
I checked the code in DefaultLettucePool and saw that the password is not used in generating RedisURI when sentinelConfiguration is involved. When I modified the code as following, it works now.
DefaultLettucePool:
private RedisURI getRedisURI() {
if (isRedisSentinelAware()) {
return LettuceConverters.sentinelConfigurationToRedisURI(sentinelConfiguration, password, getDatabase());
}
return createSimpleHostRedisURI();
}
And in LettuceConverters:
public static RedisURI sentinelConfigurationToRedisURI(RedisSentinelConfiguration sentinelConfiguration, String password, int database) {
Assert.notNull(sentinelConfiguration, "RedisSentinelConfiguration is required");
Set<RedisNode> sentinels = sentinelConfiguration.getSentinels();
RedisURI.Builder builder = null;
for (RedisNode sentinel : sentinels) {
if (builder == null) {
builder = RedisURI.Builder.sentinel(sentinel.getHost(), sentinel.getPort(), sentinelConfiguration.getMaster()
.getName());
}
else {
builder.withSentinel(sentinel.getHost(), sentinel.getPort());
}
}
if (password != null) {
builder = builder.withPassword(password);
}
builder.withDatabase(database);
return builder.build();
}

grails 2.2.4 and grails-spring-security-facebook plugin with GPmongoDB 1.3.0GA

When i use grails spring security facebook plugin with MongoDB database, it keep throwing OptimisticLockingException on these section.
Then i override it with FacebookAuthService like these.
class FacebookAuthService {
def create(FacebookAuthToken token) {
FacebookUser fbUser = new FacebookUser(uid: token.uid)
fbUser.accessToken = token.accessToken?.accessToken
fbUser.accessTokenExpires = token.accessToken?.expireAt
Facebook facebook = new FacebookTemplate(token.accessToken.accessToken)
FacebookProfile fbProfile = facebook.userOperations().userProfile
User user = User.findByUsernameOrFacebookId(fbProfile.email,fbProfile.id)
if(!user){
user = new User()
user.facebookId = fbProfile.id
user.firstname = fbProfile.firstName.toLS()
user.lastname = fbProfile.lastName.toLS()
user.gender = Gender.strToEnum(fbProfile.gender)
user.acceptTerms = true
user.acceptTermsDate = new Date()
user.accountExpired = false
user.passwordExpired = false
user.accountLocked = false
user.enabled = true
user.username = "facebook_$token.uid"
user.password = token.accessToken.accessToken
}else{
user.facebookId = fbProfile.id
}
user.save(flush: true, failOnError: true)
fbUser.user = user
Role role = Role.findByAuthority('ROLE_USER')
if (role && !user.authorities.contains(role)) {
UserRole.create(user, role)
}
fbUser.save(flush: true, failOnError: true)
return fbUser
}
def getAppUser(FacebookUser facebookUser){
return facebookUser?.user
}
Collection<GrantedAuthority> getRoles(User user){
return UserRole.findAllByUser(user)?.role?.collect{ role ->
new GrantedAuthorityImpl(role.authority)
}
}
}
But now it throws Connection wait timeout after 120000 ms. Stacktrace follows:
Message: Connection wait timeout after 120000 ms
I know there is bug with GPMONGODB driver. and fixed it like described on there.
Please help me to fix it
Grails version 2.2.4
mongodb version 2.2.4
gpmongo driver version 1.3.0GA
spring security facebook plugin version :0.14.5
also it includes thse additional plugins to collect user information.
'org.springframework.social:spring-social-core:1.0.3.RELEASE'
'org.springframework.social:spring-social-facebook:1.0.3.RELEASE'
Edit:
I found out the cause
com.the6hours.grails.springsecurity.facebook.FacebookAuthProvider class's authenticate method keeps calling on every request. So what could be the cause of this loop ?

Apache Abdera Client giving No credentials available for NTLM <any realm>#proxy.tcs.com:8080

I have seen many forum posts for this and tried several suggestions but still I am not able to solve this. The code works good at my home system, but behind the organization firewall it gives a exception message :
No credentials available for NTLM #proxy.tcs.com:8080
Here is the method which I am using
private static void UseAbdera() throws IOException
{
try
{
Abdera abdera = new Abdera();
AbderaClient client = new AbderaClient(abdera);
client.setProxy("OrgProxyHost", 8080);
NTLMAuthenticatorClass authenticator = new NTLMAuthenticatorClass("username", "password");
Authenticator.setDefault(authenticator);
NTCredentials ntcr = new NTCredentials("username", "password", "greenhouse.lotus.com", "India.TCS.com");
client.addCredentials("https://greenhouse.lotus.com", null, null, ntcr);
ClientResponse resp = client.get("https://greenhouse.lotus.com/forums/atom/service");
org.apache.abdera.model.Document<org.apache.abdera.model.Service> service_doc = resp.getDocument();
service_doc.writeTo(System.out);
System.out.println("\n");
org.apache.abdera.model.Service service = service_doc.getRoot();
org.apache.abdera.model.Collection collection = service.getCollection("Forums Feed Collection", "My Topics");
String coll_uri = collection.getResolvedHref().toASCIIString();
org.apache.abdera.model.Entry entry = abdera.newEntry();
entry.setTitle("TEST REPLY !");
// Mark private
resp = client.post(coll_uri, entry);
switch (resp.getType())
{
case SUCCESS:
String location = resp.getLocation().toASCIIString();
System.out.println("New entry created at: " + location);
break;
default:
System.out.println("Error: " + resp.getStatusText());
}
} catch (URISyntaxException ex)
{
Logger.getLogger(IBMConnectionMessages_ForumPractice.class.getName()).log(Level.SEVERE, null, ex);
}
}
This is the exception log I get
org.apache.commons.httpclient.auth.AuthChallengeProcessor selectAuthScheme
INFO: ntlm authentication scheme selected
Jul 6, 2012 10:42:03 AM org.apache.commons.httpclient.HttpMethodDirector processProxyAuthChallenge
INFO: No credentials available for NTLM #orgProxyHost:8080
Exception in thread "main" java.lang.IllegalStateException
at org.apache.abdera.protocol.client.CommonsResponse.(CommonsResponse.java:44)
at org.apache.abdera.protocol.client.AbderaClient.execute(AbderaClient.java:692)
at org.apache.abdera.protocol.client.AbderaClient.get(AbderaClient.java:216)
at org.apache.abdera.protocol.client.AbderaClient.get(AbderaClient.java:404)
at IBMConnectionMessages_ForumPractice.UseAbdera(IBMConnectionMessages_ForumPractice.java:231)
at IBMConnectionMessages_ForumPractice.main(IBMConnectionMessages_ForumPractice.java:45)
Please help, I have spent half a day on it.
your proxy may need ntlm authentication, so provide your proxy authentication details as NTCredentials while setting proxy credentials.