2017-01-12 3 views
0

Wenn (in Spring Security/MVC) der Zugriff auf eine Seite verweigert wird, da der Benutzer nicht genug Berechtigungen (obwohl er authentifiziert ist), muss ich anbieten, als anderer Benutzer über die Anzeige anmelden die Anmeldeseite (anstelle des Standardverhaltens zum Anzeigen einer 403-Zugriffs-verweigerten Seite).
Ich kann eine AccessDeniedHandler schreiben, die auf die Anmeldeseite umleitet. Aber wie wird Spring Security reagieren, wenn es herausfindet, dass bereits ein anderer Benutzer angemeldet ist? Kann ich den alten Benutzer abmelden, wenn der neue erfolgreich authentifiziert wurde?AccessDeniedHandler mit Umleitung zur Login-Seite

Antwort

1

habe ich versucht, in einen neuen Benutzer anmelden, wenn bereits ein anderer dort Benutzer angemeldet ist es funktioniert -., Ohne den ersten Benutzer abzumelden. Seine Genehmigung wird durch die neue ersetzt. Dies ist die einfache Antwort auf meine eigene Frage.

Wenn jemand interessiert ist, wie weiterleiten Seite im Fall eines Zugriffs auf Anmeldung verweigert - hier ist meine Lösung:

Zuerst eine benutzerdefinierte RequestCache definieren:

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

Zweite einen benutzerdefinierten AccessDeniedHandler definieren:

@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); 
     } 
    } 
} 

Dritte konfigurieren, dass diese zwei in Spring Security:

@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) 
    } 
} 

Was passiert hier?
Die MyAccessDeniedHandler leitet im Fall einer AccessDeniedException auf die Anmeldeseite. Da diese Weiterleitung von dieser selbst programmierten Klasse und nicht von Spring in der Filterkette aufgerufen wird, müssen wir spring sagen, was die Zielanforderung ist - wohin sie nach erfolgreicher Authentifizierung umleiten muss. Dies tun wir über die RequestCache.

0

Wenn Sie den alten Benutzer abzumelden wollen, würde ich SessionRegistry (http://docs.spring.io/spring-security/site/docs/current/apidocs/org/springframework/security/core/session/SessionRegistry.html)

Einige Hinweise unter Verwendung vorschlagen:

Im Frühjahr Konfigurationsklasse

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

In Ihrem AccessDeniedHandler:

@Autowired 
private SessionRegistry sessionRegistry; 

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

Danke - aber meine Frage war: Wie reagiert Spring, wenn man sich anmeldet wenn schon jemand eingeloggt ist - funktioniert es ohne Logout und wenn nein - wie man dieses Logout nach dem Commit der Login Seite und der Authentifizierungsprozess. Ich habe eine einfache Antwort auf diese Frage gefunden :) - bitte schauen Sie, was ich geschrieben habe. – olivmir

-1

Sie können hinzufügen folgenden Tag in Ihrem Frühling Sicherheit xml Datei.

<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> 

In Ihrem Federcontroller.

@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

Danke - aber das beantwortet nicht meine Frage, wie Spring reagiert, wenn man sich anmeldet, wenn schon jemand eingeloggt ist - funktioniert das ohne Logout und wenn nein - wie man dieses Logout nach dem Commit der Login-Seite und der Authentifizierung durchführt verarbeiten. Ich habe eine einfache Antwort auf diese Frage gefunden :) - bitte schauen Sie, was ich geschrieben habe. – olivmir