Announcement Announcement Module
Collapse
No announcement yet.
Generating a authentication success event post signin Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Generating a authentication success event post signin

    Hi,

    The SigninAdapter from the examples goes something like this
    PHP Code:
    public void signIn(String localUserId, Connection<?> connection, NativeWebRequest request) {
    Authentication auth = new UsernamePasswordAuthenticationToken(user, null,Collections.<GrantedAuthority>emptyList());
        SecurityContextHolder.getContext().setAuthentication(auth);
    }
    AFAIK, because there is no

    Authentication res = authenticationManager.authenticate(auth);

    no authentication success event is generated. Because I'm storing passwords encrypted, I can't retrieve them from the principal to execute the authenticate. I want this because I want to redirect the user to the page he originated from. Looking to do this. Any ideas?

    BTW, shouldn't Spring Social publish a successful authentication through the authenticationManager post sign in?

  • #2
    Spring Social doesn't have a dependency on Spring Security, so we expect the SigninAdapter to encapsulate the dependency on whatever security system you are using and do what you need it to. If that means calling an authManager, you can do that. It's up to your adapter, what's provided in the sample is just a sample.

    SignInAdapter isn't charged with the sign-in redirect, that's the ProviderSignInController's responsibility. I assume you need the ProviderSignInController to redirect to the original "secure URL" the user requested before being prompted for sign-in, right? This is a current limitation of ProviderSignInController we as a community should address before 1.0.

    Keith
    Last edited by Keith Donald; Jul 14th, 2011, 05:13 PM.

    Comment


    • #3
      To address this, we could either change the signature of SignInAdapter to return a String redirectUrl or add a new SignInAdapter method along the lines of "requestedUrl(NativeWebRequest request) that fetches the URL the user requested when the user was prompted for sign-in.

      Keith

      Comment


      • #4
        It would be nice if the framework would remember it without the developer having to store it, but having the option to do so if he wants.
        Two use cases:
        1. requesting the original "secure URL" (a login page is displayed and the user opts to click Twitter, Facebook etc).
        2. someone clicks a login button on a non "secure URL". This should basically just return you there after completion.

        In my case, I use a popup to access the social login page in order to not confuse users with a different site. So, I eventually return to a page that self closes the popup and reloads the opener or redirects you to the original secure url.

        Comment


        • #5
          For #1 Spring Security will save the requested URL in the session if I'm not mistaken. A Spring Security specific SignInAdapter could extract it. ProviderSignInController is written independent of the security framework so we wouldn't want to hardcode anything in there I would think.

          Have you implemented the second use case with Spring Security already? I'm not as familiar with that case.

          Not to sound like a broken record here, but a sample project showing the user interaction model you'd like to see would help move this along.

          Keith

          Comment


          • #6
            Hi, yes the second one I use also.
            I basically extend a SavedRequestAwareAuthenticationSuccessHandler that returns me to the original url the login was called from

            Comment


            • #7
              The reason the redirect is actually not happening automatically is because the signinadapter is not actually authenticating but just creating a username password authenticationtoken and storing that in the securitycontext.
              If an actual authentication would be executed, it would publish the authentication event that would lead to the redirect to the originating page.

              Comment


              • #8
                return redirect url

                I think returning a redirectUrl would be best.

                PHP Code:
                ProviderSigninController
                private RedirectView handleSignIn(Connection<?> connection, NativeWebRequest request) {
                    String userId = usersConnectionRepository.findUserIdWithConnection(connection);
                    if (userId == null) {
                        ProviderSignInAttempt signInAttempt = new ProviderSignInAttempt(connection, connectionFactoryLocator, usersConnectionRepository);
                        request.setAttribute(ProviderSignInAttempt.SESSION_ATTRIBUTE, signInAttempt, RequestAttributes.SCOPE_SESSION);
                        return redirect(signUpUrl);
                    } else {
                        String customRedirectUrl = signInAdapter.signIn(userId, connection, request);
                        if(customRedirectUrl == null)
                            return redirect(postSignInUrl);
                        return redirect(customRedirectUrl);
                    }            
                }

                /**
                 * Adapter that bridges between a {@link ProviderSignInController} and a application-specific user sign-in service.
                 * Invoked at the end of a provider sign-in attempt to sign-in the local user account associated with the provider user account.
                 * @author Craig Walls
                 */
                public interface SignInAdapter {

                    /**
                     * Complete a provider sign-in attempt by signing in the local user account with the specified id.
                     * @param userId the local user id
                     * @param connection the connection
                     * @param request a reference to the current web request; is a "native" web request instance providing access to the native
                     * request and response objects, such as a HttpServletRequest and HttpServletResponse, if needed
                     */
                    String signIn(String userId, Connection<?> connection, NativeWebRequest request);

                }

                SimpleSigninAdapter
                @Override
                public String signIn(String localUserId, Connection<?> connection, NativeWebRequest request) {
                    Usor user = userMgr.getUser(localUserId);
                    Authentication auth = new UsernamePasswordAuthenticationToken(user, null,user.getAuthorities());
                    SecurityContextHolder.getContext().setAuthentication(auth);
                    
                    request.setAttribute(MYAPP.USER_KEY, user, RequestAttributes.SCOPE_SESSION);
                    
                    DefaultSavedRequest savedRequest = (DefaultSavedRequest) request.getAttribute(WebAttributes.SAVED_REQUEST,RequestAttributes.SCOPE_SESSION);
                    if(savedRequest != null)
                        return savedRequest.getRedirectUrl();
                    return null;
                }

                Comment


                • #9
                  https://jira.springsource.org/browse/SOCIAL-227

                  Comment


                  • #10
                    Thanks...I was already looking into this, but thanks for creating the JIRA issue to make it official. Will be digging into this later today.

                    Comment


                    • #11
                      Remember again you can make *your* SignInAdapter do whatever you want; so if performing an "actual authentication" would generate the event and redirect you need, could you try that? I'm pretty confused at this point, since it seems you wouldn't need to return anything then (yet in subsequent posts you seem to think its necessary after all).

                      Comment


                      • #12
                        No, I can't do an actual authentication, because I store my passwords in encrypted fashion. So it's one way only.
                        But I resolved it by adding this to my PostSigninController

                        @RequestMapping(method = RequestMethod.GET, value = "/postsignin")
                        public String signUpPostConnect(ModelMap model, NativeWebRequest request) {
                        DefaultSavedRequest savedRequest = (DefaultSavedRequest) request.getAttribute(WebAttributes.SAVED_REQUEST,R equestAttributes.SCOPE_SESSION);

                        if(savedRequest != null){
                        request.removeAttribute(WebAttributes.SAVED_REQUES T,RequestAttributes.SCOPE_SESSION);
                        model.addAttribute("redirectUrl", savedRequest.getRedirectUrl());
                        }

                        actually, I think I'm there. Now I'm prettying up the sign up process. Thanks for the help so far. When I start on the connect controller, you'll prob hear from me again :-)
                        I'll send you a link once it's up for review.

                        Comment


                        • #13
                          Yes, it would be great if you could post the full source of what you went with, as I'm pretty confused as to what you're doing. I assume you still would find the change to SignInAdapter to allow returning a redirectUrl desirable.

                          Keith

                          Comment


                          • #14
                            I could prob expand a little on the jpaTemplate to add the actual configs and controllers. I would still change the signin adapter, yes

                            Comment

                            Working...
                            X