2017-10-29 11 views
2

中にユーザーを登録します。春のセキュリティ:私は2つのエンドポイントでサービスを持っているランタイム

  1. 公開エンドポイント:誰もがそれにアクセスし、ユーザーアカウントを開くことができます(登録)エンドポイント保護
  2. :唯一の登録ユーザは、HTTP POSTリクエスト

会社の一環として認証ヘッダーを使用することによって、それをアクセスすることができますE-ケース:

  • ユーザーが最初公共の終点にヒットし、HTTP POSTによってuserNameを含むJSONをアカウントを開きます。サービスはパスワードを生成し、それをJSON応答としてユーザーに返します。
  • ユーザーがバックサービスからパスワードを得た後、彼は認証ヘッダー今

で彼の資格情報を渡すことで保護されたエンドポイントにアクセスするために(彼userNameと一緒に)このpasswordを使用する必要があります明らかに、ランタイムの間に新しいユーザを登録する必要があります。

私が直面している問題は、最初のユーザーが公開エンドポイントに登録すると、その瞬間に保護されたエンドポイントにアクセスするための認証が不要になることです。すべての資格情報が有効になり、承認済みヘッダーのないリクエストさえも機能します。なぜ私はこの種の悪い行為をしているのか分からないので、それを修正する方法についてのアドバイスは素晴らしいことでしょう!ユーザーを開くために

公開エンドポイントは

@RequestMapping(method = RequestMethod.POST, value = "/user", produces = "application/json") 
public ResponseEntity<UserCreatedResponse> create(@RequestBody String userName) { 
     // generate user password 
     String password = service.generatePassword(); 

     // save the user to the local repository 
     service.save(userName, password); 

     // use SecurityService to add a new user token --> something fishy here! 
     security.login(userName, password); 


     // returns response with a new user password 
     return new ResponseEntity<UserCreatedResponse>(
       new UserCreatedResponse(password), 
       HttpStatus.CREATED); 
} 

を占めUserService.javaはSecurityService.javaリポジトリに

public void save(String userName, String password) { 
    repository.save(new User(userName, passwordEncoder.encode(password))); 
} 

をユーザーを保存するために使用されるログインの資格情報を格納するために使用されます:これが正しいかどうかわからない

public void login(String userName, String password) { 
     // usrDetailsService is the instance of UserDetailsService.java 
     UserDetails usrDetails = usrDetailsService.loadUserByUsername(userName); 

     UsernamePasswordAuthenticationToken token = 
       new UsernamePasswordAuthenticationToken(usrDetails, password, usrDetails.getAuthorities()); 

     // authenticate token with the given account details 
     authManager.authenticate(token); 

     if (token.isAuthenticated()) { 
      // provide authentication info to the context 
      SecurityContextHolder.getContext().setAuthentication(token); 
     } 
    } 

UserDetailsS​​ervice.java

public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException { 
    // this is my custom User class 
    User user = repository.findById(userName); 

    // and this is org.springframework.security.core.userdetails.User 
    return new User(user.getUsername(), user.getPasswordHash(), Collections.emptySet()); 
} 

保護された(認可)エンドポイント

@RequestMapping(method = RequestMethod.POST, value = "/hello", produces = "application/json") 
public String hello(@RequestBody MyRequest request) { 
    return "Hello, authenticated!"; 
} 

SecurityConfig。Javaの

@Configuration 
@EnableWebSecurity 
public class SecurityConfig extends WebSecurityConfigurerAdapter { 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 

     http.authorizeRequests() 
          .antMatchers(HttpMethod.POST, "/user") 
          .permitAll().anyRequest().authenticated(); 

     http.csrf().disable(); 
    } 
} 

は再び、希望の動作は次のとおりです。

  • に新しいユーザーアカウントを作成 "はlocalhost:8080 /ユーザーを"
  • そして "ローカルホスト:8080/hello" をヒットauthenthicationが必要です上記登録されたユーザーのために、それ以外の場合Unathorized何が不足している応答

またはワットで応答私は間違っているのですか?

+0

誰でも手助けできます。それは、 "/ user"コントローラが新しいユーザーを登録するためにヒットしたときにユーザーにログインし、認証されたコントローラ "/ hello"を呼び出した後、もう認証を要求しません。それを修正するには? – wesleyy

答えて

0

セキュリティ設定はどのようになっていますか? 登録するページを指定することができます。

/** 
    * Configures the access rights for the application. 
    * 
    * @param http the HttpSecurity context of the application 
    * @throws Exception some exception. 
    */ 
    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
    http.authorizeRequests() 
     //Which URLs are available without any authentication 
     .antMatchers("/about", "/help", "/imprint", "/register", "/registerExp", "/login**").permitAll() 
     //Restrict access rights for any relative URL behind /admin/ to the ADMIN role 
     .antMatchers("/admin/**").hasRole("ADMIN") 
     //Any request needs to be fully authenticated (remember me does NOT suffice!) 
     .anyRequest().fullyAuthenticated().and() 
     //Specify the login process. 
     .formLogin() 
      .loginPage("/login") 
      .failureHandler(authenticationHandler) 
      .permitAll() 
      .and().logout().permitAll() 
      .and() 
     .csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()).ignoringAntMatchers("/console/**"); 

    //Disables header security. This allows the use of the h2 console. 
    http.headers().frameOptions().disable(); 
    } 
+0

SecurityConfigクラスが追加されました – wesleyy

+0

基本的にはセキュリティコンフィグとして必要なものがすべて用意されていますが、私はログインフォームを持たないためformLogin()部分がありません。 on認証ヘッダー。私は "/ user"エンドポイントに登録した後に "/ hello"コントローラにヒットしたときにログインの詳細を要求しない理由を理解していません。 "/ hello"を登録する前に承認が必要ですが、登録後は許可されません。それは...どんなアイデアですか? – wesleyy

+0

登録後に新しいユーザーを承認しているからです。 'security.login(userName、password);' SecurityContextHolder.getContext()。setAuthentication(token);で認証を設定します。あなたのユーザーは再びログインすることなくすべての保護されたサイトにアクセスできます。 – Viergelenker

関連する問題