2016-11-12 4 views
1

Ich versuche Zugriff auf eine Seite dashboard.html nicht authentifizierte Benutzer aufgerufen zu beschränken. Bis jetzt hatte ich keinen Erfolg. Hier ist mein WebSecurityConfigurerAdapter:Wie Zugriff auf .html Seiten beschränken REST mit Spring-Boot

@Configuration 
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER) 
public class CustomWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter { 

    @Autowired 
    private CustomAuthenticationSuccessHandler authenticationSuccessHandler; 

    @Autowired 
    private CustomAuthenticationFailureHandler authenticationFailureHandler; 

    @Autowired 
    private CustomUserDetailsService userDetailsService; 

    @Autowired 
    private TokenAuthenticationService tokenAuthenticationService; 

    @Bean 
    public BCryptPasswordEncoder passwordEncoder() { 
     return new BCryptPasswordEncoder(); 
    } 

    @Bean 
    @Override 
    public AuthenticationManager authenticationManagerBean() throws Exception { 
     return super.authenticationManagerBean(); 
    } 

    @Override 
    protected void configure(AuthenticationManagerBuilder builder) throws Exception { 
     builder.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder()); 
    } 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
     http 
      .authorizeRequests() 
       .antMatchers("/index.html", "/", 
         "/login.html","/signup.html", "/videos/**", 
         "/login", "/logout", "/images/**", "/fonts/**", 
         "/css/**", "/js/**", "/pages/**", "/sass/**" 
         ).permitAll() 
       .and() 
      .authorizeRequests() 
       .antMatchers("/dashboard/**", "/dashboard.html/**").authenticated()   
       .and() 
      .authorizeRequests() 
       .anyRequest().authenticated() 
       .and() 
      .addFilterBefore(new StatelessLoginFilter("/login", tokenAuthenticationService, userDetailsService, authenticationManager()), UsernamePasswordAuthenticationFilter.class) 
      .addFilterBefore(new StatelessAuthenticationFilter(tokenAuthenticationService), UsernamePasswordAuthenticationFilter.class) 
      .formLogin() 
       .loginPage("/login.html") 
       .loginProcessingUrl("/login") 
       .usernameParameter("email") 
       .passwordParameter("password") 
       .successHandler(authenticationSuccessHandler) 
       .failureHandler(authenticationFailureHandler) 
       .and() 
      .logout() 
       .logoutSuccessUrl("/") 
       .deleteCookies("JSESSIONID") 
       .permitAll() 
       .and() 
      .csrf() 
       .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()) 
       .and() 
      .addFilterAfter(new CsrfTokenFilter(), CsrfFilter.class); 
    } 
} 

Jedes Mal, wenn ich es so einrichten, wenn ich versuche, um sich einzuloggen, eine unendliche Schleife Umleitung verursacht wird. Der Browser versucht, zu dashboard.html zu navigieren, ist jedoch eingeschränkt. Dies führt zu einer Umleitung auf die Anmeldeseite, die versucht, auf das Dashboard umzuleiten, da ein gültiges Token vorhanden ist.

Wenn ich es wie folgt einstellen, können alle dashboard.html zugreifen und Anrufe an den /dashboard Endpunkt machen was nicht erwünscht ist:

  http 
       .authorizeRequests() 
        .antMatchers("/index.html", "/", 
          "/login.html","/signup.html", "/videos/**", 
          "/login", "/logout", "/images/**", "/fonts/**", 
          "/css/**", "/js/**", "/pages/**", "/sass/**", 
          "/dashboard/**", "/dashboard.html/**").permitAll() 
        .and() 
       .authorizeRequests() 
        .anyRequest().authenticated() 

Mein Login JWT Token verwendet und verwendet die folgenden Filter, um die SecurityContext einstellen Platzhalter:

class StatelessLoginFilter extends AbstractAuthenticationProcessingFilter { 

    private final TokenAuthenticationService tokenAuthenticationService; 

    private final CustomUserDetailsService userDetailsService; 

    protected StatelessLoginFilter(String urlMapping, TokenAuthenticationService tokenAuthenticationService, 
      CustomUserDetailsService userDetailsService, AuthenticationManager authManager) { 
     super(new AntPathRequestMatcher(urlMapping)); 
     this.userDetailsService = userDetailsService; 
     this.tokenAuthenticationService = tokenAuthenticationService; 
     setAuthenticationManager(authManager); 
    } 

    @Override 
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) 
      throws AuthenticationException, IOException, ServletException { 
     final BusinessUser user = new ObjectMapper().readValue(request.getInputStream(), BusinessUser.class); 
     final UsernamePasswordAuthenticationToken loginToken = new UsernamePasswordAuthenticationToken(
       user.getEmail(), user.getPassword()); 
     return getAuthenticationManager().authenticate(loginToken); 
    } 

    @Override 
    protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, 
      FilterChain chain, Authentication authentication) throws IOException, ServletException { 

     final BusinessUser authenticatedUser = userDetailsService.loadUserByUsername(authentication.getName()); 
     final UserAuthentication userAuthentication = new UserAuthentication(authenticatedUser); 

     tokenAuthenticationService.addAuthentication(response, userAuthentication); 

     SecurityContextHolder.getContext().setAuthentication(userAuthentication); 
    } 

ich bin mit der Linie SecurityContextHolder.getContext().setAuthentication(userAuthentication); die Authentifizierung einzustellen. Das funktioniert ganz gut. Wenn ein Benutzer in der DB gefunden wird, um die Anmeldeinformationen für: vom Benutzer gesendet werden, dann ist der Sicherheitskontext verschiedene Daten dem Benutzer zugeordnet abzurufen verwendbar.

meine Frage: Wie kann ich beschränken die Seite dashboard.html und ruft zum /dashboard Endpunkt nicht authentifizierte Benutzer (die ohne Authentifizierung Objekt innerhalb des SecurityContextHolder)?

+0

sind Sie sicher, dass Sie alle geben „/“ in Erlaubnis, wahrscheinlich, dass es alle – kuhajeyan

Antwort

3

Sie können eine benutzerdefinierte RequestMatcher in Kombination mit denyAll verwenden. Zuerst Ihre benutzerdefinierten Matcher:

public class PermittedPagesMatcher implements RequestMatcher { 

    @Override 
    public boolean matches(HttpServletRequest httpServletRequest) { 
     if (matchesToPaths(httpServletRequest,"/index.html", "/", "/login.html","/signup.html", "/videos/**", "/login", "/logout", "/images/**", "/fonts/**", "/css/**", "/js/**", "/pages/**", "/sass/**", "/dashboard/**", "/dashboard.html/**")) { 
      return true; 
     } 

     if (matchesToPaths(httpServletRequest, "/dashboard/**", "/dashboard.html/**")) { 
      return httpServletRequest.getUserPrincipal() == null; 
     } 

     return false; 
    } 

    private boolean matchesToPaths(HttpServletRequest httpServletRequest, String... paths) { 
     for (String p : paths) { 
      if (new AntPathRequestMatcher(p).matches(httpServletRequest)) { 
       return true; 
      } 
     } 
     return false; 
    } 
} 

Diese benutzerdefinierten RequestMatcher filtert Ihre Anfrage gestattet Seiten, um alle Ihre Standardseiten und das Armaturenbrett ist nur verfügbar, wenn die Anfrage nicht authentifiziert ist.

Zweitens verbinden die Matcher und denyAll()

http 
      .authorizeRequests() 
      .requestMatchers(new PermittedPagesMatcher()) 
      .permitAll() 
     .and() 
      .antMatchers("/dashboard/**", "/dashboard.html/**") 
      .denyAll() 
     .and() 
      .authorizeRequests() 
      .anyRequest() 
      .authenticated() 

denyAll() gewährleistet, dass standardmäßig wird niemand auf diese Seite zuzugreifen erlaubt.

Achtung: Die Reihenfolge der Genehmigung und Verweigerung ist wichtig!

+0

ich es zugreifen können nicht während unauthenticated wollen, damit verursacht. Mit dieser Einrichtung kann ich immer noch darauf zugreifen, auch wenn ich kein Authentifizierungstoken habe. Ich veränderte die return-Anweisung zu: 'Rückkehr httpServletRequest.getUserPrincipal() = null;', da es nur wahr zurückgeben sollte, wenn es ein authentifizierter Benutzer. Jetzt stoße ich auf dasselbe Problem. Niemand darf jetzt auf "dashboard.html" zugreifen. Selbst wenn sie authentifiziert sind. Ich möchte nur authentifizierte/eingeloggte Benutzer Zugriff auf das Dashboard.html haben. Ich kann nur jeden dazu bringen, darauf zuzugreifen, oder niemandem, der sofort darauf zugreifen kann. –

+0

Ich bin verwirrt ... Zitat: _How kann ich einschränken [...] ruft zu [...], um nicht authentifizierten users._ Wenn Sie nur authentifizierte Benutzer zulassen möchten, entfernen Sie '„/ Armaturenbrett/**“' und "/dashboard.html/**" 'von' http.authorizeRequests(). antMatchers (....) 'von deinem ursprünglichen Code und du bist gut zu gehen. – Schrieveslaach

+0

Ich habe jedoch ein Problem mit meinem ursprünglichen Setup. Aus irgendeinem Grund kann ich mit diesem Setup nicht auf "/ dashboard.html" zugreifen, egal ob ich authentifiziert bin oder nicht.Ich habe sogar den Wert von 'httpServletRequest.getUserPrincipal()! = Null;' ausgedruckt und gibt true zurück. Das heißt, es gibt einen authentifizierten Benutzer, aber aus irgendeinem Grund kann ich nicht auf "/ dashboard.html" zugreifen. –

Verwandte Themen