Hi -- I'm trying to figure out how to implement Spring Security 4 relogin with "v9.1p_2015-02-07/Pro Deployment", but I'm losing the transaction somehow. I've read the example from 5 years ago:
http://forums.smartclient.com/showthread.php?t=9633
but that was implemented with Smart GWT, and I can't find a good example for SmartClient. Also, perhaps Spring Security has changed since then.
Here's my login.jsp:
and bootstrapped from one of the Spring Security samples (and not carefully cleaned up yet), my WEB-INF/spring/security.xml:
Does my login.jsp look more or less correct? I disabled CSRF tokens for now because I want to figure out relogin before adding that. As far as I can tell, I'm able to login the way it's supposed to work.
I can use my page to relogin too... although I'm losing my transaction somehow. I put a print statement inside handleLoginRequired and
is printing null. I can't figure out what's going on with isc.showConsole() because when my session times out, the page redirects to login.jsp when an IDACall gets access denied, and everything in the ISC console gets cleared. I get the login dialog from my login.jsp and not the expected relogin dialog in reloginFlow.js (i.e. the login dialog still works, but I lost my transaction).
Here's my Catalina log near the redirect:
On a related note... I'm not sure how to handle loginSuccessMarker.html with Spring Security. In your documentation, you said I should be able to either POST credentials to loginSuccessMarker.html or have my authentication system return the contents of loginSuccessMarker.html as a part of a successful response. I can't find an option in Spring Security for the former option. In the Smart GWT examples, the later approach was taken and loginSuccessMarker was embedded as a string in some Java code, but I don't see how to do this from SmartClient. For example, there doesn't appear to be an appropriate place for these contents in security.xml for example.
One idea I had was for relogin to take two POST steps. The first would target /login with the credentials, and the second would target loginSuccessMarker.html. That's probably not the simplest approach. It's also irrelevant if the transaction number was lost as I described above.
What am I misunderstanding?
Thanks so much!!
http://forums.smartclient.com/showthread.php?t=9633
but that was implemented with Smart GWT, and I can't find a good example for SmartClient. Also, perhaps Spring Security has changed since then.
Here's my login.jsp:
Code:
<%@ taglib uri="/WEB-INF/iscTaglib.xml" prefix="isomorphic" %> <%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %> <!DOCTYPE html> <HTML><HEAD><TITLE>My Login Page</TITLE> <SCRIPT SRC=./isomorphic/system/modules-debug/ISC_Core.js></SCRIPT> <SCRIPT SRC=./isomorphic/system/modules-debug/ISC_Foundation.js></SCRIPT> <SCRIPT SRC=./isomorphic/system/modules-debug/ISC_Containers.js></SCRIPT> <SCRIPT SRC=./isomorphic/system/modules-debug/ISC_Grids.js></SCRIPT> <SCRIPT SRC=./isomorphic/system/modules-debug/ISC_Forms.js></SCRIPT> <SCRIPT SRC=./isomorphic/system/modules-debug/ISC_DataBinding.js></SCRIPT> <SCRIPT SRC=./isomorphic/login/reloginFlow.js></SCRIPT> <SCRIPT SRC=./isomorphic/skins/Graphite/load_skin.js></SCRIPT> </HEAD><BODY> <SCRIPT> isc.RPCManager.credentialsURL = "/secured/loginSuccessMarker.html"; isc.showLoginDialog(function (credentials, dialogCallback){ var request = isc.RPCRequest.create({ actionURL: "/secured/login", httpMethod: "POST", params: {username: credentials.username, password: credentials.password}, useSimpleHttp: true, containsCredentials: true, callback: function(rpcResponse,rpcRequest){ var success = rpcResponse.status == isc.RPCResponse.STATUS_SUCCESS; dialogCallback(success); if(success){ window.location = "index.jsp"; } }, }); isc.RPCManager.sendRequest(request); }); </SCRIPT> <SCRIPT>//'"]]>>isc_loginRequired // // Embed this whole script block VERBATIM into your login page to enable // SmartClient RPC relogin. //======= if (!window.isc && document.domain && document.domain.indexOf(".") != -1 && !(new RegExp("^(\\d{1,3}\\.){3}\\d{1,3}$").test(document.domain))) { var set = false; while (document.domain.indexOf(".") != -1) { try { if (window.opener && window.opener.isc) break; if (window.top.isc) break; if (!set) { document.domain = document.domain; set = true; } else { document.domain = document.domain.replace(/.*?\./, ''); } } catch (e) { try { if (!set) { document.domain = document.domain; set = true } else { document.domain = document.domain.replace(/.*?\./, ''); } } catch (ee) { break; } } } } var isc = top.isc ? top.isc : window.opener ? window.opener.isc : null; if (isc && isc.RPCManager) isc.RPCManager.delayCall("handleLoginRequired", [window]); </SCRIPT> </BODY> </HTML>
Code:
<beans:beans xmlns="http://www.springframework.org/schema/security" xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd"> <debug /> <http pattern="/isomorphic/system/**" security="none"/> <http pattern="/isomorphic/locales/**" security="none"/> <http pattern="/isomorphic/login/*js" security="none"/> <http pattern="/isomorphic/skins/**" security="none"/> <http pattern="/src/**" security="none"/> <http pattern="/js/**" security="none"/> <http pattern="/css/**" security="none"/> <http pattern="/images/**" security="none"/> <http pattern="/loginDialog.js" security="none"/> <http> <intercept-url pattern="/login.jsp*" access="permitAll"/> <intercept-url pattern="/**" access="isAuthenticated()" /> <intercept-url pattern="/isomorphic/IDACall*" access="isAuthenticated()" /> <intercept-url pattern="/isomorphic/login/loginSuccessMarker.html" access="isAuthenticated()" /> <csrf disabled="true"/> <form-login login-page="/login.jsp" /> <logout delete-cookies="JSESSIONID" /> <remember-me /> </http> <!-- Usernames/Passwords are rod/koala dianne/emu scott/wombat peter/opal --> <beans:bean id="encoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/> <authentication-manager> <authentication-provider> <password-encoder ref="encoder"/> <user-service> <user name="rod" password="$2a$10$75pBjapg4Nl8Pzd.3JRnUe7PDJmk9qBGwNEJDAlA3V.dEJxcDKn5O" authorities="supervisor, user, teller" /> <user name="dianne" password="$2a$04$bCMEyxrdF/7sgfUiUJ6Ose2vh9DAMaVBldS1Bw2fhi1jgutZrr9zm" authorities="user,teller" /> <user name="scott" password="$2a$06$eChwvzAu3TSexnC3ynw4LOSw1qiEbtNItNeYv5uI40w1i3paoSfLu" authorities="user" /> <user name="peter" password="$2a$04$8.H8bCMROLF4CIgd7IpeQ.tcBXLP5w8iplO0n.kCIkISwrIgX28Ii" authorities="user" /> </user-service> </authentication-provider> </authentication-manager> </beans:beans>
I can use my page to relogin too... although I'm losing my transaction somehow. I put a print statement inside handleLoginRequired and
Code:
var transaction = this.getTransaction(transactionNum); console.log("transaction:",transaction);
Here's my Catalina log near the redirect:
Code:
16:10:28.855 [http-bio-8080-exec-27] DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - Secure object: FilterInvocation: URL: /isomorphic/IDACall?isc_rpc=1&isc_v=v9.1p_2015-02-07&isc_xhr=1; Attributes: [isAuthenticated()] 16:10:28.856 [http-bio-8080-exec-27] DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - Previously Authenticated: org.springframework.security.authentication.AnonymousAuthenticationToken@90541710: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@166c8: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: 5FC2D60009E5DD456B06D30921520331; Granted Authorities: ROLE_ANONYMOUS 16:10:28.856 [http-bio-8080-exec-27] DEBUG o.s.s.access.vote.AffirmativeBased - Voter: org.springframework.security.web.access.expression.WebExpressionVoter@772e499b, returned: -1 16:10:28.857 [http-bio-8080-exec-27] DEBUG o.s.s.w.a.ExceptionTranslationFilter - Access is denied (user is anonymous); redirecting to authentication entry point org.springframework.security.access.AccessDeniedException: Access is denied at org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.java:83) ~[spring-security-core-4.0.1.CI-SNAPSHOT.jar:na] ... 16:10:28.858 [http-bio-8080-exec-27] DEBUG o.s.s.w.s.HttpSessionRequestCache - DefaultSavedRequest added to Session: DefaultSavedRequest[http://localhost:8080/secured/isomorphic/IDACall?isc_rpc=1&isc_v=v9.1p_2015-02-07&isc_xhr=1] 16:10:28.858 [http-bio-8080-exec-27] DEBUG o.s.s.w.a.ExceptionTranslationFilter - Calling Authentication entry point. 16:10:28.858 [http-bio-8080-exec-27] DEBUG o.s.s.web.DefaultRedirectStrategy - Redirecting to 'http://localhost:8080/secured/login.jsp' 16:10:28.858 [http-bio-8080-exec-27] DEBUG o.s.s.w.c.HttpSessionSecurityContextRepository - SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession. 16:10:28.858 [http-bio-8080-exec-27] DEBUG o.s.s.w.c.SecurityContextPersistenceFilter - SecurityContextHolder now cleared, as request processing completed
On a related note... I'm not sure how to handle loginSuccessMarker.html with Spring Security. In your documentation, you said I should be able to either POST credentials to loginSuccessMarker.html or have my authentication system return the contents of loginSuccessMarker.html as a part of a successful response. I can't find an option in Spring Security for the former option. In the Smart GWT examples, the later approach was taken and loginSuccessMarker was embedded as a string in some Java code, but I don't see how to do this from SmartClient. For example, there doesn't appear to be an appropriate place for these contents in security.xml for example.
One idea I had was for relogin to take two POST steps. The first would target /login with the credentials, and the second would target loginSuccessMarker.html. That's probably not the simplest approach. It's also irrelevant if the transaction number was lost as I described above.
What am I misunderstanding?
Thanks so much!!
Comment