モバイルアプリがサーバーに接続して情報を取得できるようにするサービスを実装しようとしています。
Spring Security を CustomUserDetail に含めましたが、ログイン フォームを使用せずに、Json でデータを受信し、ユーザーを手動でログに記録しました
Authentication authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(authentication);
今、MongoDB を使用して記憶サービスを実装する必要がありますが、DB に保存されているトークンを取得できません。ユーザーをログに記録するときに「remember-me」チェックをシミュレートするにはどうすればよいですか? そうしないと、サーバーを再起動するたびにすべてのユーザーがログアウトされるため、必須です
これは私のセキュリティ設定ファイルです:
<http use-expressions="true">
<remember-me services-ref="rememberMeServices" key="myPersistentKey" />
<logout invalidate-session="true" logout-url="/logout" />
<intercept-url pattern="/users/**" access="isAuthenticated()" />
<intercept-url pattern="/**" access="permitAll" />
<form-login authentication-failure-url="/denied" login-page="/denied" />
<access-denied-handler error-page="/denied" />
</http>
<beans:bean id="customUserDetailsService" class="com.service.test.security.CustomUserDetailsService" />
<authentication-manager alias="authenticationManager">
<authentication-provider user-service-ref="customUserDetailsService">
<password-encoder hash="md5" />
</authentication-provider>
</authentication-manager>
<beans:bean id="mongoDBTokenRepository" class="com.service.test.security.MongoPersistentTokenRepositoryImpl" />
<beans:bean id="rememberMeServices"
class="org.springframework.security.web.authentication.rememberme.PersistentTokenBasedRememberMeServices">
<beans:constructor-arg value="myPersistentKey" />
<beans:constructor-arg ref="customUserDetailsService" />
<beans:constructor-arg ref="mongoDBTokenRepository" />
<beans:property name="alwaysRemember" value="true" />
</beans:bean>
PersistentTokenRepository の私の実装である MongoPersistentTokenRepositoryImpl
@Autowired
private RememberMeTokenRepository rememberMeTokenRepository;
@Override
public void createNewToken(PersistentRememberMeToken token) {
RememberMeToken newToken = new RememberMeToken(token);
this.rememberMeTokenRepository.save(newToken);
}
@Override
public void updateToken(String series, String tokenValue, Date lastUsed) {
RememberMeToken token = this.rememberMeTokenRepository.findBySeries(series);
if (token != null) {
token.setTokenValue(tokenValue);
token.setDate(lastUsed);
this.rememberMeTokenRepository.save(token);
}
}
@Override
public PersistentRememberMeToken getTokenForSeries(String seriesId) {
RememberMeToken token = this.rememberMeTokenRepository.findBySeries(seriesId);
return new PersistentRememberMeToken(token.getUsername(), token.getSeries(), token.getTokenValue(), token.getDate());
}
@Override
public void removeUserTokens(String username) {
List<RememberMeToken> tokens = this.rememberMeTokenRepository.findByUsername(username);
this.rememberMeTokenRepository.delete(tokens);
}
これは UserDetailsService を実装する私の CustomUserDetailsService です
@Autowired
private UserRepository userRepository;
/**
* Returns a populated {@link UserDetails} object. The username is first retrieved from the database and then mapped
* to a {@link UserDetails} object.
*/
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
try {
User21 domainUser = userRepository.findByEmail(email);
boolean enabled = true;
boolean accountNonExpired = true;
boolean credentialsNonExpired = true;
boolean accountNonLocked = true;
return new CustomUser(domainUser.getId(), domainUser.getEmail(), domainUser.getPassword().toLowerCase(), enabled, accountNonExpired, credentialsNonExpired, accountNonLocked,
// getAuthorities(domainUser.getRole().getRole()));
getAuthorities(2));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* Returns a populated {@link UserDetails} object. The username is first retrieved from the database and then mapped
* to a {@link UserDetails} object.
*/
public UserDetails loadUser(User21 user) throws UsernameNotFoundException {
try {
boolean enabled = true;
boolean accountNonExpired = true;
boolean credentialsNonExpired = true;
boolean accountNonLocked = true;
return new CustomUser(user.getId(), user.getEmail(), user.getPassword().toLowerCase(), enabled, accountNonExpired, credentialsNonExpired, accountNonLocked,
// getAuthorities(domainUser.getRole().getRole()));
getAuthorities(2));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* Retrieves a collection of {@link GrantedAuthority} based on a numerical role
*
* @param role
* the numerical role
* @return a collection of {@link GrantedAuthority
*/
public Collection<? extends GrantedAuthority> getAuthorities(Integer role) {
List<GrantedAuthority> authList = getGrantedAuthorities(getRoles(role));
return authList;
}
/**
* Converts a numerical role to an equivalent list of roles
*
* @param role
* the numerical role
* @return list of roles as as a list of {@link String}
*/
public List<String> getRoles(Integer role) {
List<String> roles = new ArrayList<String>();
if (role.intValue() == 1) {
roles.add("ROLE_USER");
roles.add("ROLE_ADMIN");
} else if (role.intValue() == 2) {
roles.add("ROLE_USER");
}
return roles;
}
/**
* Wraps {@link String} roles to {@link SimpleGrantedAuthority} objects
*
* @param roles
* {@link String} of roles
* @return list of granted authorities
*/
public static List<GrantedAuthority> getGrantedAuthorities(List<String> roles) {
List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
for (String role : roles) {
authorities.add(new SimpleGrantedAuthority(role));
}
return authorities;
}
public void logUserIn(User21 user) throws Exception{
UserDetails userDetails = loadUser(user);
Authentication authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(authentication);
}
私はこの素晴らしい記事に基づいて開発しました
http://www.jiwhiz.com/post/2013/2/Add_RememberMe_Authentication_With_Spring_Security
しかし、私が見逃しているものがあるに違いありません。
ありがとう!