Wednesday, January 24, 2018

Spring session replication with mongodb not working as expected

Leave a Comment

I am replicating session using mongodb

below is the configuration I am using

@Configuration @EnableMongoHttpSession public class MongoSessionReplication {  @Bean public AbstractMongoSessionConverter mongoSessionConverter() {     List<Module> securityModules = SecurityJackson2Modules.getModules(getClass().getClassLoader());     return new JacksonMongoSessionConverter(securityModules); } @Bean public MongoTemplate mongoTemplate(@Qualifier("replicaSet") Datastore replicaSet){    MongoTemplate mongoTemplate = new MongoTemplate(replicaSet.getMongo(),replicaSet.getDB().getName());    return mongoTemplate; }  } 

Now everything is working fine except the Principal object that spring security creates after loggin in. I have custom implementation of UserDetails

public class PortalUser extends User {      private String primaryEmailId;      private String redirectUrl;      public PortalUser(String username, String password, boolean enabled, boolean accountNonExpired, boolean credentialsNonExpired, boolean accountNonLocked, Collection<? extends GrantedAuthority> authorities) {         super(username, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities);     }     public PortalUser(String username, String password, Collection<? extends GrantedAuthority> authorities) {         super(username, password, true, true, true, true, authorities);     }      public String getPrimaryEmailId() {         return primaryEmailId;     }      public void setPrimaryEmailId(String primaryEmailId) {         this.primaryEmailId = primaryEmailId;     }      public String getRedirectUrl() {         return redirectUrl;     }      public void setRedirectUrl(String redirectUrl) {         this.redirectUrl = redirectUrl;     } } 

Below is UserDetailsService

@Service public class PortalUserDetailService implements UserDetailsService {      @Autowired     private SSOServiceAPI ssoServiceAPI;      @Autowired     private UserProfileService userProfileService;      @Override     public UserDetails loadUserByUsername(String hexId) throws UsernameNotFoundException {         UserProfile userProfile = userProfileService.getUserProfileByUserId(hexId);         List<GrantedAuthority> grantedAuthority = new ArrayList<GrantedAuthority>();         if(userProfile!=null) {             grantedAuthority.add(new SimpleGrantedAuthority(userProfile.getSsmRoles().name()));         } else {             grantedAuthority.add(new SimpleGrantedAuthority("USER"));         }         SSOUsers ssoUser = ssoServiceAPI.findSSOUser(hexId, false);         PortalUser portalUser = new PortalUser(hexId, hexId, true, true, true, true, grantedAuthority);         portalUser.setPrimaryEmailId(ssoUser.getPrimaryUserId());         return portalUser;      } } 

Controller

public String getAllProducts(@RequestParam(value = "callback", required = true) String callback, Principal principal, HttpServletRequest request) {      String hexId = principal.getName();     String primaryEmailId = ((PortalUser) ((UsernamePasswordAuthenticationToken) principal).getPrincipal()).getPrimaryEmailId(); //----->> this line fails  } 

Above highlighted typecasting failed as it returns instance of UserDetails instead of my custom PortalUser. But this isn't a case when I disable spring-session replication..

1 Answers

Answers 1

You need to extend Spring's Security UserDetails, not User. update PortUser to the below:

import org.springframework.security.core.userdetails.UserDetails;  public class PortalUser  extends UserDetails,Serializable { 
If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment