セキュリティを使用してログインしたとき、request.isUserInRole()
メソッドを使用できません。ユーザーの役割が設定されていないと思います。
これは私のセキュリティ構成です:
_@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled=true)
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private DataSource dataSource;
@Autowired
private UserDetailsServiceImplementation userDetailsService;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/signup").permitAll()
.antMatchers("/").permitAll()
//.antMatchers("/first").hasAuthority("Service_Center")
.antMatchers("/login").permitAll()
.anyRequest().fullyAuthenticated()
.and().formLogin()
.loginPage("/login")
.usernameParameter("email")
.passwordParameter("password")
.defaultSuccessUrl("/default")
.failureUrl("/login?error").permitAll()
.and().logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/login?logout")
.deleteCookies("JSESSIONID")
.invalidateHttpSession(true).permitAll();
}
@Autowired
public void configAuthentication(AuthenticationManagerBuilder auth)
throws Exception {
auth.userDetailsService(userDetailsService);
}
}
_
これは私のUser
エンティティです:
_ @Entity
@Table(name="user")
public class User implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name="user_id")
private Long userID;
@Column(name="email_address", nullable = false, unique = true)
private String emailAddress;
@Column(name="password")
private String password;
@Column(name = "role", nullable = false)
@Enumerated(EnumType.STRING)
private Role role;
public User() {
super();
}
public User(String emailAddress, String password) {
this.emailAddress = emailAddress;
this.password = password;
}
public Long getUserID() {
return userID;
}
public void setUserID(Long userID) {
this.userID = userID;
}
public String getEmailAddress() {
return emailAddress;
}
public void setEmailAddress(String emailAddress) {
this.emailAddress = emailAddress;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Role getRole() {
return role;
}
public void setRole(Role role) {
this.role = role;
}
@Override
public String toString() {
return "User [userID=" + userID + ", emailAddress=" + emailAddress
+ ", password=" + password + ", role=" + role + "]";
}
public UserDetails toCurrentUserDetails() {
return CurrentUserDetails.create(this);
}
}
_
これは私のRole
です:
_public enum Role {
Fleet_Company, Service_Center, Admin
}
_
これは私のUserDetailsServiceImplementation
です:
_@Component
public class UserDetailsServiceImplementation implements UserDetailsService {
@Autowired
private UserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException {
if ( username == null || username.isEmpty() ){
throw new UsernameNotFoundException("username is empty");
}
User foundUser = userRepository.findByEmailAddress(username);
if( foundUser != null ){
System.out.println("FOUND");
return foundUser.toCurrentUserDetails();
}
throw new UsernameNotFoundException( username + "is not found");
}
}
_
これは、UserDetails
を実装するクラスです。
_public class CurrentUserDetails implements UserDetails {
private Long userID;
private String emailAddress;
private String password;
private Role role;
public CurrentUserDetails(Long userID, String emailAddress, String password, Role role) {
super();
this.userID = userID;
this.emailAddress = emailAddress;
this.password = password;
this.role = role;
}
/* public static UserDetails create(Users entity) {
List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
for(Authorities auth: entity.getAuthorities()){
authorities.add(new SimpleGrantedAuthority(auth.getId().getAuthority()));
}
return new MyUserDetail(entity.getUserId(), entity.getLoginId(), entity.getPassword(), entity.getDisplayName(), authorities);
}*/
public Long getUserID(){
return this.userID;
}
public Role getRole(){
return this.role;
}
@Override
public String getPassword() {
return this.password;
}
public String getEmailAddress() {
return this.emailAddress;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
public static UserDetails create(User entity) {
System.out.println(entity.getUserID()+ entity.getEmailAddress()+ entity.getPassword()+ entity.getRole());
return new CurrentUserDetails(entity.getUserID(), entity.getEmailAddress(), entity.getPassword(), entity.getRole());
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
// TODO Auto-generated method stub
return null;
}
@Override
public String getUsername() {
// TODO Auto-generated method stub
return null;
}
}
_
基本的に、MySQLデータベースにはテーブルが1つしかなく、4つの列があり、そのうちの1つが「ロール」であることがわかります。
しかし、私が言ったように、request.isUserInRole("Service_Center")
を使用すると、FALSEを返します。 .antMatchers("/first").hasAuthority("Service_Center")
も機能しません。
UserDetailsを作成するときは、ロールのコンテンツを自分で入力する必要があります。
public class SecurityUser implements UserDetails{
String ROLE_PREFIX = "ROLE_";
String userName;
String password;
String role;
public SecurityUser(String username, String password, String role){
this.userName = username;
this.password = password;
this.role = role;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
List<GrantedAuthority> list = new ArrayList<GrantedAuthority>();
list.add(new SimpleGrantedAuthority(ROLE_PREFIX + role));
return list;
}
基本的に、必要なのはメソッドgetAuthorities
をオーバーライドし、ロールフィールドの内容をGrantedAuthority
リストに入力することです。
ロールを追加するには、ユーザー名とそれに対応するロールを含むテーブルが必要です。
ユーザーに2つのロール、つまりADMINとUSERがあるとします
1人のユーザーが複数の役割を持つことができます。
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
final List<SimpleGrantedAuthority> authorities = new LinkedList<>();
if (enabled) {
if (this.getUser().isAdmin()) {
authorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
}
authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
}
return authorities;
}
これは、
private UsernamePasswordAuthenticationToken getAuthentication(
final String token, final HttpServletRequest req,
final HttpServletResponse res){
return new UsernamePasswordAuthenticationToken(userAccount, null,
userAccount.getAuthorities());
}
Divelnto、zapl、thorinkorが言ったことは正しい。しかし、質問は「役割」ではなく「役割」についてでなければなりません。または、ユーザーとロールを1つのテーブルに入れている場合、その設計は不適切です。設計アプローチを再検討することをお勧めします。別の役割エンティティが必要です。また、UserServiceで次のようなことができます。
AppUser user = userRepository.findByUsername(username);
Set<GrantedAuthority> grantedAuthorities = new HashSet<>(); // use list if you wish
for (AppRole role : user.getRoles()) {
grantedAuthorities.add(new SimpleGrantedAuthority(role.getName()));
}
return new org.springframework.security.core.userdetails.User(
user.getUsername(),
user.getPassword(),
grantedAuthorities
);
参考のため、こちらをご覧ください。
---(春のセキュリティ関連1