2016-10-07 57 views
-1

我想在我的java代碼中編寫一些腳本,我需要登錄用戶,做一些像真實用戶可以從web客戶端和每個人登出的東西。如何在Spring Security中的Java代碼中登錄用戶?

這是如何在春季安全工作? 我該怎麼辦? 我的意思是如何模仿真實的用戶認證,會話,角色和權限?

非常感謝!

回答

1

過一段時間後,我發現的解決方案:

@Component 
public class AuthorityUtils { 

//org.springframework.security.authentication.AuthenticationManager 
@Autowired 
private AuthenticationManager authenticationManager; 

public void loginDirectly(String email, String password) { 
    UsernamePasswordAuthenticationToken loginToken = new UsernamePasswordAuthenticationToken(email, password); 
    Authentication authenticatedUser = authenticationManager.authenticate(loginToken); 
    SecurityContextHolder.getContext().setAuthentication(authenticatedUser); 
    } 
} 
0

請試試這個例子:

創建Spring Security Java Configuration。

@Configuration 
@EnableWebSecurity 
public class SecurityConfiguration extends WebSecurityConfigurerAdapter { 

    @Autowired 
    @Qualifier("customUserDetailsService") 
    UserDetailsService userDetailsService; 

    @Autowired 
    PersistentTokenRepository tokenRepository; 

    @Autowired 
    public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception { 
     auth.userDetailsService(userDetailsService); 
     auth.authenticationProvider(authenticationProvider()); 
    } 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
     http.authorizeRequests().antMatchers("/", "/list") 
       .access("hasRole('USER') or hasRole('ADMIN') or hasRole('DBA')") 
       .antMatchers("/newuser/**", "/delete-user-*").access("hasRole('ADMIN')").antMatchers("/edit-user-*") 
       .access("hasRole('ADMIN') or hasRole('DBA')").and().formLogin().loginPage("/login") 
       .loginProcessingUrl("/login").usernameParameter("ssoId").passwordParameter("password").and() 
       .rememberMe().rememberMeParameter("remember-me").tokenRepository(tokenRepository) 
       .tokenValiditySeconds(86400).and().csrf().and().exceptionHandling().accessDeniedPage("/Access_Denied"); 
    } 

    @Bean 
    public PasswordEncoder passwordEncoder() { 
     return new BCryptPasswordEncoder(); 
    } 

    @Bean 
    public DaoAuthenticationProvider authenticationProvider() { 
     DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider(); 
     authenticationProvider.setUserDetailsService(userDetailsService); 
     authenticationProvider.setPasswordEncoder(passwordEncoder()); 
     return authenticationProvider; 
    } 

    @Bean 
    public PersistentTokenBasedRememberMeServices getPersistentTokenBasedRememberMeServices() { 
     PersistentTokenBasedRememberMeServices tokenBasedservice = new PersistentTokenBasedRememberMeServices(
       "remember-me", userDetailsService, tokenRepository); 
     return tokenBasedservice; 
    } 

    @Bean 
    public AuthenticationTrustResolver getAuthenticationTrustResolver() { 
     return new AuthenticationTrustResolverImpl(); 
    } 

} 

的Spring Security帶有兩個執行PersistentTokenRepository的:JdbcTokenRepositoryImplInMemoryTokenRepositoryImpl最好

@Repository("tokenRepositoryDao") 
@Transactional 
public class HibernateTokenRepositoryImpl extends AbstractDao<String, PersistentLogin> 
     implements PersistentTokenRepository { 

    static final Logger logger = LoggerFactory.getLogger(HibernateTokenRepositoryImpl.class); 

    @Override 
    public void createNewToken(PersistentRememberMeToken token) { 
     logger.info("Creating Token for user : {}", token.getUsername()); 
     PersistentLogin persistentLogin = new PersistentLogin(); 
     persistentLogin.setUsername(token.getUsername()); 
     persistentLogin.setSeries(token.getSeries()); 
     persistentLogin.setToken(token.getTokenValue()); 
     persistentLogin.setLast_used(token.getDate()); 
     persist(persistentLogin); 

    } 

    @Override 
    public PersistentRememberMeToken getTokenForSeries(String seriesId) { 
     logger.info("Fetch Token if any for seriesId : {}", seriesId); 
     try { 
      Criteria crit = createEntityCriteria(); 
      crit.add(Restrictions.eq("series", seriesId)); 
      PersistentLogin persistentLogin = (PersistentLogin) crit.uniqueResult(); 

      return new PersistentRememberMeToken(persistentLogin.getUsername(), persistentLogin.getSeries(), 
        persistentLogin.getToken(), persistentLogin.getLast_used()); 
     } catch (Exception e) { 
      logger.info("Token not found..."); 
      return null; 
     } 
    } 

    @Override 
    public void removeUserTokens(String username) { 
     logger.info("Removing Token if any for user : {}", username); 
     Criteria crit = createEntityCriteria(); 
     crit.add(Restrictions.eq("username", username)); 
     PersistentLogin persistentLogin = (PersistentLogin) crit.uniqueResult(); 
     if (persistentLogin != null) { 
      logger.info("rememberMe was selected"); 
      delete(persistentLogin); 
     } 

    } 

    @Override 
    public void updateToken(String seriesId, String tokenValue, Date lastUsed) { 
     logger.info("Updating Token for seriesId : {}", seriesId); 
     PersistentLogin persistentLogin = getByKey(seriesId); 
     persistentLogin.setToken(tokenValue); 
     persistentLogin.setLast_used(lastUsed); 
     update(persistentLogin); 
    } 

} 

以上實現使用Entity [PersistentLogin]映射到persistent_logins表,如下所示是實體本身。

@Entity 
@Table(name="PERSISTENT_LOGINS") 
public class PersistentLogin implements Serializable{ 

    @Id 
    private String series; 

    @Column(name="USERNAME", unique=true, nullable=false) 
    private String username; 

    @Column(name="TOKEN", unique=true, nullable=false) 
    private String token; 

    @Temporal(TemporalType.TIMESTAMP) 
    private Date last_used; 

    public String getSeries() { 
     return series; 
    } 

    public void setSeries(String series) { 
     this.series = series; 
    } 

    public String getUsername() { 
     return username; 
    } 

    public void setUsername(String username) { 
     this.username = username; 
    } 

    public String getToken() { 
     return token; 
    } 

    public void setToken(String token) { 
     this.token = token; 
    } 

    public Date getLast_used() { 
     return last_used; 
    } 

    public void setLast_used(Date last_used) { 
     this.last_used = last_used; 
    } 


} 

這個UserDetailsS​​ervice實現,在安全配置中使用如下圖所示:

@Service("customUserDetailsService") 
public class CustomUserDetailsService implements UserDetailsService{ 

    static final Logger logger = LoggerFactory.getLogger(CustomUserDetailsService.class); 

    @Autowired 
    private UserService userService; 

    @Transactional(readOnly=true) 
    public UserDetails loadUserByUsername(String ssoId) 
      throws UsernameNotFoundException { 
     User user = userService.findBySSO(ssoId); 
     logger.info("User : {}", user); 
     if(user==null){ 
      logger.info("User not found"); 
      throw new UsernameNotFoundException("Username not found"); 
     } 
      return new org.springframework.security.core.userdetails.User(user.getSsoId(), user.getPassword(), 
       true, true, true, true, getGrantedAuthorities(user)); 
    } 


    private List<GrantedAuthority> getGrantedAuthorities(User user){ 
     List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>(); 

     for(UserProfile userProfile : user.getUserProfiles()){ 
      logger.info("UserProfile : {}", userProfile); 
      authorities.add(new SimpleGrantedAuthority("ROLE_"+userProfile.getType())); 
     } 
     logger.info("authorities : {}", authorities); 
     return authorities; 
    } 

} 

最後,註冊使用下述初始化類應用戰爭springSecurityFilter。

public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer { 

} 
+0

份額白衣我們烏爾知識或者如果u有更好的想法..而不是否決不需要任何理由! – FuSsA

+0

如果你問我,我還沒有投票。 說實話,我剛剛看到,開始工作,並投了票 作出詳細迴應。我也不知道,爲什麼有人投票否決了這個問題。至少有兩個人最喜歡這個問題。 – DamienMiheev

+0

我知道這不是你......;) – FuSsA

相關問題