11

私はSpring Securityにログインした後、アクション必須画面を実装しようとしていますか?私はフォームを完了するためにユーザーが実行しなければならない要件があります(パスワードの変更、利用規約の受け入れなど)。ユーザーがそのアクションを完了すると、彼はアプリケーションの残りの部分を使用できます。私は、Springセキュリティフローを使用するログイン画面で、Spring OAuth2を使用しています。ログイン後の春のセキュリティと対応

これまで私はSavedRequestAwareAuthenticationSuccessHandlerのカスタム実装を持つhttp.formLogin().successHandler()を使用しようとしましたが、これはユーザーに必要なアクションがあるかどうかを検出し、フォームを記入できるときにユーザーをページにリダイレクトしますが、そのページから移動すると、彼はアプリにログインし、フォームをスキップすることなく使用することができます。しかし、私がやろうとしているのは、アクション要求フォームが完了するまで、ユーザーがセッションを確立できないようにすることです。ユーザーが完全にログインすると自動的にログインする必要があります(たとえば、利用規約に同意する必要がある場合は、2回目のパスワードを入力せずにログインする必要があります)。

ここにコードがあります遠くカスタムハンドラ:

public class CustomLoginSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler { 

    @Autowired 
    UserService userService; 

    public final static String TARGET_URL_SESSION_ATTR_NAME = "target-url"; 

    public CustomLoginSuccessHandler(String defaultTargetUrl) { 
     setDefaultTargetUrl(defaultTargetUrl); 
    } 

    @Override 
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws ServletException, IOException { 
     HttpSession session = request.getSession(); 


     AuthorityUser authorityUser = (AuthorityUser)authentication.getPrincipal(); 

     String userId = authorityUser.getUserId(); 

     User u = userService.getById(userId); 

     Boolean changeRequiredDob = u.getChangeRequiredDob(); 
     Boolean changeRequiredPwd = u.getChangeRequiredPwd(); 
     Boolean changeRequiredTou = u.getChangeRequiredTou(); 

     if(changeRequiredDob || changeRequiredPwd || changeRequiredTou){ 

      String targetUrl = determineTargetUrl(request, response); 
      session.setAttribute(TARGET_URL_SESSION_ATTR_NAME, targetUrl); 
      getRedirectStrategy().sendRedirect(request, response, "/action-required"); 
     } else { 
      super.onAuthenticationSuccess(request, response, authentication); 
     } 
    } 
} 

そして、それは私がセッションに格納されていたTARGET_URL_SESSION_ATTR_NAMEにユーザーをリダイレクトしています正常に完了したら。

確立されたセッション中にユーザーが必要なアクションを検出してリダイレクトする方法を知っておくと便利です(ユーザーがログインした後で、管理者がログインしているときにアカウントで必要なアクションフラグが設定されている場合)。

+0

通常のフィルタ(/にマップされている)にこのロジックを実装すると、a)ユーザーはそれから離れてナビゲートできなくなり、b)ユーザーは自動的に「ログイン」するか、むしろ通過した。あなたが実装する必要があるかもしれない追加だけが、成功のための適切なリダイレクトです。 – chimmi

+0

すぐにセッションを作成したくないという実際の理由はありますか? – chimmi

答えて

3

https://github.com/king-julien/spring-oauth2-customfilterここに、承認とリソースサーバーを使用した実例があります。このリソースサーバー(バニラ)は、認証後に利用規約(TOSを受け入れるため、ちょうどPOST on/tosエンドポイントを受け入れる)を受け入れるまで、これ以上進まない基本的なステートレスアプリケーションです。

フィルタ

@Configuration 
public class SecurityConfig extends WebSecurityConfigurerAdapter { 

    @Autowired 
    TosFilter rolesFilter; 

    @Override 
    public void configure(HttpSecurity httpSecurity) throws Exception{ 

     httpSecurity 
       .addFilterAfter(rolesFilter, AbstractPreAuthenticatedProcessingFilter.class) 
       .csrf().disable() 
       .authorizeRequests().anyRequest().permitAll(); 
    } 
} 

が@EnableResourceServerとあなたの主な注釈を付けることをフィルタ

@Component 
public class TosFilter extends OncePerRequestFilter{ 

    @Override 
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) 
      throws ServletException, IOException { 
     System.out.println(request.getRequestURI()); 

     // In realworld scenario HelloWorldController.acceptedTOS is a persisted value rather than a static variable 
     if(!HelloWorldController.acceptedTOS){ 
      //response.sendRedirect("/no-tos"); 
      request.getRequestDispatcher("error-no-tos").forward(request, response); 
     } 
     filterChain.doFilter(request,response); 
    } 
} 

登録を作成します。

@SpringBootApplication 
@EnableResourceServer 
public class Application { 

    public static void main(String[] args) { 
     SpringApplication.run(Application.class, args); 
    } 

} 
1

私たちが解決する方法は、OAuth2承認ページを単一ページアプリケーションにすることです。 デフォルトでは、承認ページコントローラはWhitelabelApprovalEndpointです。 "/ oauth/confirm_access"をオーバーライドする独自のOauthApproval Controllerを定義することでこれをオーバーライドするので、追加のものをモデルに追加できます。承認(jsp)ページが読み込まれると、モデルのプロパティの一部がjavascript変数(var token = '$ {_ csrf.token}')に変換され、AngularJSアプリケーションが起動します。承認ページでは、(実際の承認フォームを表示する前に)何でもできますが、さまざまな機能に対してRESTエンドポイントを作成するだけで済みます。

することができます成功したセッションにログイン時のユーザーのアクセス権を検証する別の方法は、フィルタAPI経由で

https://www.mkyong.com/spring-mvc/how-to-register-a-servlet-filter-in-spring-mvc/

コントローラ

+0

私はOAuth2とfamilliarではありませんが、これは、カスタムアクションはリソースサーバーではなく承認サーバーによって処理されなければならないということですか? – chimmi

0

に(「authorizationRequest」)@SessionAttributesを追加することを忘れないでくださいdoFilter()で必要な機能を実装してルールを検証します。

1

代わりのAuthenticationSuccessHandlerあなたは、フィルタを使用する必要があります。

public class ActionRequirementCheckingFilter extends OncePerRequestFilter { 

    /* This matcher should not match static resources (js,css etc), 
    * url`s needed to handle the action and possibly something else, 
    * depending on your application */ 
    private RequestMatcher matcher; 

    @Override 
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { 
     HttpSession session = request.getSession(); 
     Boolean actionRequired = false; 

     /* calculate actual value for actionRequired */ 

     if(matcher.matches(request) && actionRequired){ 

      /* save current request info into session for later use if needed */ 

      response.sendRedirect("/action-required"); 
     } else { 
      filterChain.doFilter(request, response); 
     } 
    } 

} 

このアプローチは、すべてのあなたのrequirmentsにフィット:

  • ユーザーが文句を言わないユーザーが自動的になります離れてそれから
  • をナビゲートすることができるようログイ完了後のアクションが完了しました
  • 既存のセッションでも機能します

アクションが完了する前にセッションが実際に作成されますが、あなたがそれをしない本当の理由がない限り(これはイメージングでさえも)無視できます。

関連する問題