Page 1 of 1

OpenId authentication success handling

Posted: Sat May 18, 2013 12:21 pm
by Sambhav
I was able to authenticate using OpenId in my BLC app.

Simplified use case:-

1. User already registered using his gmail id.
2. Onl login page , he should be able to login using google.

Changes made:-

1. applicationContext-security.xml


Code: Select all

<sec:openid-login user-service-ref="myUserDetailsService" authentication-success-handler-ref="openIdAuthSuccessHandler">
         <sec:attribute-exchange>
            <sec:openid-attribute name="email"
               type="http://axschema.org/contact/email" required="true" />
            <sec:openid-attribute name="axNamePersonFirstName"
               type="http://axschema.org/namePerson/first" required="true" />
            <sec:openid-attribute name="axNamePersonLastName"
               type="http://axschema.org/namePerson/last" required="true" />
         </sec:attribute-exchange>
      </sec:openid-login>


Code: Select all

<bean class="com.mycompany.service.security.openid.OpenIdUserDetailsService" id="myUserDetailsService"/>


Code: Select all

<bean class="com.mycompany.service.security.openid.BizzgrassOpenIdSuccessHandler" id="openIdAuthSuccessHandler"/>



2. My user details service :-

Code: Select all

public class OpenIdUserDetailsService implements UserDetailsService,
      AuthenticationUserDetailsService<OpenIDAuthenticationToken> {

   @Autowired(required = true)
   @Qualifier(value = "blUserDetailsService")
   private UserDetailsService localUserDetailsService;

   /**
    * @return the localUserDetailsService
    */
   public UserDetailsService getLocalUserDetailsService() {
      return localUserDetailsService;
   }

   /**
    * @param localUserDetailsService
    *            the localUserDetailsService to set
    */
   public void setLocalUserDetailsService(
         UserDetailsService localUserDetailsService) {
      this.localUserDetailsService = localUserDetailsService;
   }

   @Override
   public UserDetails loadUserDetails(OpenIDAuthenticationToken token)
         throws UsernameNotFoundException {
      String email = getEmail(token);
      return loadUserByUsername(email);
   }

   @Override
   public UserDetails loadUserByUsername(String username)
         throws UsernameNotFoundException {
      return localUserDetailsService.loadUserByUsername(username);
   }

   private String getEmail(OpenIDAuthenticationToken token) {
      for (OpenIDAttribute attribute : token.getAttributes()) {
         if (attribute.getName().equals("email")) {
            return attribute.getValues().get(0);
         }
      }
      return null;
   }

}



3. Authentication handler:-

Code: Select all

public class BizzgrassOpenIdSuccessHandler extends
      BroadleafAuthenticationSuccessHandler {

   @Resource(name = "blCustomerService")
   protected CustomerService customerService;

   /**
    * @return the customerService
    */
   public CustomerService getCustomerService() {
      return customerService;
   }

   /**
    * @param customerService
    *            the customerService to set
    */
   public void setCustomerService(CustomerService customerService) {
      this.customerService = customerService;
   }

   @Override
   public void onAuthenticationSuccess(HttpServletRequest request,
         HttpServletResponse response, Authentication authentication)
         throws ServletException, IOException {
      super.onAuthenticationSuccess(request, response, authentication);
      Customer customer = customerService
            .readCustomerByEmail(getEmail(authentication));
      CustomerState.setCustomer(customer);
   }

   private String getEmail(Authentication authentication) {
      User user = (User) authentication.getPrincipal();
      return user.getUsername();
   }

}



Questions:-

1. Is this approach correct?
2. The effect of sucessfull authenticatoin is not reflected in UI / flow.
For e.g the header section still shows Login / Register link.

Code: Select all

<div th:if="${customer.anonymous}"  th:remove="tag">
            <a class="account" th:href="@{/login}">Login</a>
            &nbsp;|&nbsp;
            <a class="account" th:href="@{/register}">Register</a>
            &nbsp;|&nbsp;
         </div>


In my success handler code I have used:-

Code: Select all

Customer customer = customerService
            .readCustomerByEmail(getEmail(authentication));
      CustomerState.setCustomer(customer);


and still its not passed as request attribute to view layer. I do get a customer object returned by customerService

What is purpose of CustomerState class?

Please help me fix this.

Thanks a lot.