2017-01-12 24 views
0

(Spring Security/MVCで)ページへのアクセスが拒否された場合、ユーザーが十分な特権を持っていない(彼は認証されていますが)ので、ログインページ(403アクセス拒否ページを表示する標準的な動作ではなく)。
AccessDeniedHandlerと書くと、ログインページにリダイレクトされます。しかし、Spring Securityは、別のユーザがログインしていることがわかった場合、どのように反応しますか?新しいユーザーが正常に認証されたら、古いユーザーを何とかログアウトできますか?ログインページにリダイレクトされたAccessDeniedHandler

答えて

1

すでにログインしている別のユーザーがいるときに新しいユーザーにログインしようとしました。最初のユーザーをログアウトせずに動作します。彼の許可は新しいものに置き換えられます。これは私自身の質問に対する簡単な答えです。アクセスの場合はログインページに転送する方法を

誰かが興味を持っている場合は、拒否されました - ここに私のソリューションです:

まず、カスタムRequestCacheを定義します。

@Component("myRequestCache") 
public class MyRequestCache extends HttpSessionRequestCache { 
    public MyRequestCache() { 
     super(); 
    } 
} 

第二には、カスタムAccessDeniedHandlerを定義します。

@Component("myAccessDeniedHandler") 
public class MyAccessDeniedHandler implements AccessDeniedHandler { 

    @Autowired 
    @Qualifier("myRequestCache") 
    private RequestCache myRequestCache; 

    public MyAccessDeniedHandler() { 
    } 

    @Override 
    public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException exc) 
     throws IOException, ServletException { 

     if (!response.isCommitted()) { 

      //Save Target-Request 
      shopRequestCache.saveRequest(request, response); 

      //Forward to the login page 
      request.getRequestDispatcher("/loginPage").forward(request, response); 
     } 
    } 
} 

サード春のセキュリティにこれら二つを設定します。

@Configuration 
@EnableWebSecurity 
public class myConfig extends WebSecurityConfigurerAdapter { 

    @Autowired 
    @Qualifier("myRequestCache") 
    RequestCache myRequestCache; 

    @Autowired 
    @Qualifier("myAccessDeniedHandler") 
    AccessDeniedHandler myAccessDeniedHandler; 

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

     http 
     .requestCache() 
      .requestCache(myRequestCache) 
      .and() 
     .exceptionHandling() 
      .accessDeniedHandler(myAccessDeniedHandler) 
    } 
} 

ここで何が起こっているか
AccessDeniedExceptionの場合、MyAccessDeniedHandlerがログインページに転送されます。このフォワードは、フィルタチェーン内のSpringではなく、この自己プログラミングされたクラスによって呼び出されるため、目的のリクエストが何であるかを春に伝えなければなりません。これはRequestCacheで行います。

0

古いユーザーをログアウトしたい場合は、私はSessionRegistryhttp://docs.spring.io/spring-security/site/docs/current/apidocs/org/springframework/security/core/session/SessionRegistry.html)を使用してお勧めし

いくつかのヒント:あなたのAccessDeniedHandlerでSpring構成クラスで

@Configuration 
class MyConfiguration{ 
    @Bean 
    public SessionRegistry sessionRegistry() { 
     return new SessionRegistryImpl(); 
    } 
} 

@Autowired 
private SessionRegistry sessionRegistry; 

.... 
List<SessionInformation> sessionInformations = sessionRegistry.getAllSessions("an-user", false); 
    for(SessionInformation session: sessionInformations) { 
     session.expireNow(); 
    } 
+0

ありがとうございます - 私が質問したのは、すでに誰かがログインしているとログインすると、どのように反応するのですか?ログアウトなしでも動作しますか?いいえ、ログインページのコミット後にこのログアウトを実行する方法認証プロセス。私はこの質問への簡単な答えを見つけました:) - 私が書いたものを見てください。 – olivmir

-1

あなたの春のセキュリティのxmlファイルのタグに続く。

<http auto-config="true" use-expressions="true"> 
      <access-denied-handler error-page="/accessDenied" /> 
     <intercept-url pattern="/publicIndex1" access="isAnonymous()"/> 
     <intercept-url pattern="/index1" access="isAnonymous()"/> 
     <!-- Restrict URLs based on role --> 
     <intercept-url pattern="/#/publicIndex" access="isAnonymous()" /> 

    <form-login 
     login-page="/publicIndex1" 
     always-use-default-target="false" 
     default-target-url="/index"  
     authentication-failure-url="/publicIndex1" 
     username-parameter="username" 
     password-parameter="password" /> 
    <logout logout-success-url="/index1" 
    delete-cookies="JSESSIONID" 
    logout-url="/logout" 
    invalidate-session="true" /> 
</http> 

スプリングコントローラでは、

@RequestMapping(value = "/accessDenied", method = RequestMethod.GET) 
public ModelAndView accessDenied() { 
    System.out.println("access denied page call"); 
    return new ModelAndView("accessDenied"); 
} 

@RequestMapping(value = "/#/publicIndex", method = RequestMethod.GET) 
public ModelAndView login(@RequestParam(value = "error", required = false) String error, 
     @RequestParam(value = "logout", required = false) String logout) { 
    System.out.println("inside /#/public index"); 
    ModelAndView model = new ModelAndView(); 
    if (error != null) { 
     model.addObject("error", "Invalid username and password!"); 
    } 
    System.out.println("**********************" + error); 
    if (logout != null) { 
     model.addObject("msg", "You've been logged out successfully."); 
    } 
    model.setViewName("publicIndex"); 
    return model; 
} 

@RequestMapping(value = "/logout", method = RequestMethod.GET) 
public String logout1() { 
    System.out.println(); 
    User user1 = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); 
    return userService.addUserOffline(user1.getUserId()); 
} 

@RequestMapping(value = "/index", method = RequestMethod.GET) 
public ModelAndView index() { 
    System.out.println("Redirect Controller Call"); 
    User user = new User(); 
    try { 
     user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); 
    } catch (Exception e) { 
     return new ModelAndView("publicIndex1"); 
    } 
    long userId = user.getUserId(); 
    userService.addLastLoginDate(userId); 
    System.out.println("user id==" + userId); 
    return new ModelAndView("index"); 

} 

@RequestMapping(value = "/index1", method = RequestMethod.GET) 
public ModelAndView index1() { 
    System.out.println("inside logout index1"); 
    Authentication auth = SecurityContextHolder.getContext().getAuthentication(); 
    if (!(auth instanceof AnonymousAuthenticationToken)) { 
     return new ModelAndView("/index"); 
    } else { 
     return new ModelAndView("index1"); 
    } 
} 
+1

ありがとうございます - しかし、これは私の質問に答えることはできません、Springがどのように反応し、誰かがログインしている場合にログインする方法 - ログアウトなしで動作するかどうか - ログインページと認証のコミット後にこのログアウトを実行する方法プロセス。私はこの質問への簡単な答えを見つけました:) - 私が書いたものを見てください。 – olivmir

関連する問題