Spring起動アプリケーションでは、メモリ内のSpring Security設定があります。それは必要に応じて動作します。"SecurityContextにAuthenticationオブジェクトが見つかりませんでした" - SpringブートのUserDetailsService設定
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("kevin").password("password1").roles("USER").and()
.withUser("diana").password("password2").roles("USER", "ADMIN");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.httpBasic().and()
.authorizeRequests()
.antMatchers(HttpMethod.POST, "/foos").hasRole("ADMIN")
.antMatchers(HttpMethod.PUT, "/foos/**").hasRole("ADMIN")
.antMatchers(HttpMethod.PATCH, "/foos/**").hasRole("ADMIN")
.antMatchers(HttpMethod.DELETE, "/foos/**").hasRole("ADMIN")
.and()
.csrf().disable();
}
}
ここでは、次のコードを使用してデータベースベースのアプローチに変換します。
@Entity
class Account {
enum Role {ROLE_USER, ROLE_ADMIN}
@Id
@GeneratedValue
private Long id;
private String userName;
// @JsonIgnore
private String password;
@ElementCollection(fetch = FetchType.EAGER)
Set<Role> roles = new HashSet<>();
...
}
リポジトリ:
@RepositoryRestResource
interface AccountRepository extends CrudRepository<Account, Long>{
@PreAuthorize("hasRole('USER')")
Optional<Account> findByUserName(@Param("userName") String userName);
}
UserDetailsService:
@Component
class MyUserDetailsService implements UserDetailsService {
private AccountRepository accountRepository;
MyUserDetailsService(AccountRepository accountRepository){
this.accountRepository = accountRepository;
}
@Override
public UserDetails loadUserByUsername(String name) throws UsernameNotFoundException {
Optional<Account> accountOptional = this.accountRepository.findByUserName(name);
if(!accountOptional.isPresent())
throw new UsernameNotFoundException(name);
Account account = accountOptional.get();
return new User(account.getUserName(), account.getPassword(),
AuthorityUtils.createAuthorityList(account.getRoles().stream().map(Account.Role::name).toArray(String[]::new)));
}
}
そしてWebSecurityConfigurerAdapter構成の変更:
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
class SecurityConfiguration extends WebSecurityConfigurerAdapter {
private MyUserDetailsService userDetailsService;
SecurityConfiguration(MyUserDetailsService userDetailsService){
this.userDetailsService = userDetailsService;
}
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService); // <-- replacing the in-memory anthentication setup
}
...
}
私は同じ要求を送信します「私ができる、いくつかの関連ドキュメントとサンプルコードを読んだ後
{
"timestamp": 1489430818803,
"status": 401,
"error": "Unauthorized",
"message": "An Authentication object was not found in the SecurityContext",
"path": "/foos"
}
:基本認証では、メモリ版用としてとしてユーザー名とパスワードのペアで、私は、しかし、401エラーが出ますエラーの原因を確認してください。エラーメッセージは、ユーザーがSpring Securityのコンテキストにないことを示しています。 userDetailsService(userDetailsService)内のAuthenticationManagerBuilderの使用行は、SecurityContextでこれらのユーザーを設定する必要がありますか?
スプリングブートバージョンは1.4.3.RELEASEです。
入力いただきありがとうございます。 preAuhorizeアノテーションを削除した後で動作します。エラーメッセージは認証に関するものですが、承認に関するものではありません。また、エラー応答メッセージに記載されているパスはfooについてですが、アカウントではありません。 URLのセキュリティ設定に関しては、httpメソッドで定義することもできます。 – vic