Spring Boot 安全性:在 Angular 8 中显示登录页面时出现问题

Posted

技术标签:

【中文标题】Spring Boot 安全性:在 Angular 8 中显示登录页面时出现问题【英文标题】:SpringBoot security : Issue while showing login page in Angular 8 【发布时间】:2020-06-10 03:08:29 【问题描述】:

我正在为我的项目实现登录功能。在前端,我使用的是 Angular 8。 我已经以这种方式实现了 Angular 8 和 Springboot 在同一个端口 8090 上运行。

我有路由

const routes: Routes = [
   path: '', component: EmployeeComponent,canActivate:[AuthGaurdService] ,
   path: 'addemployee', component: AddEmployeeComponent,canActivate:[AuthGaurdService],
   path: 'login', component: LoginComponent ,
   path: 'logout', component: LogoutComponent,canActivate:[AuthGaurdService] ,
];

Java 方面:我已经将它设置为允许所有 /login 请求

网络安全配置

 @Override
    protected void configure(HttpSecurity httpSecurity)
        throws Exception
    
        // We don't need CSRF for this example
        httpSecurity.csrf().disable()
            // dont authenticate this particular request
            .authorizeRequests().antMatchers("/login").permitAll()
            .antMatchers(HttpMethod.OPTIONS, "/**").permitAll().anyRequest().authenticated().and().
            // make sure we use stateless session; session won't be used to
            // store user's state.
            exceptionHandling().authenticationEntryPoint(jwtAuthenticationEntryPoint).and()
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
        // Add a filter to validate the tokens with every request
        httpSecurity.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
    

但仍然在调用 localhost:8090/login 时,我面对的是浏览器

Whitelabel 错误页面 此应用程序没有明确的映射 /error,因此您将其视为后备。

IST 2020 年 2 月 26 日星期三 14:42:50 出现意外错误(类型=Not 找到,状态=404)。没有可用的消息

在后台,我正面临

2020-02-26 14:30:44.045 警告 5184 --- [nio-8090-exec-1] org.freelancing.utils.JwtRequestFilter :JWT 令牌不开始 带有承载字符串 2020-02-26 14:42:49.945 WARN 5184 --- [nio-8090-exec-3] org.freelancing.utils.JwtRequestFilter:JWT 令牌 不以承载字符串 2020-02-26 14:42:51.287 WARN 5184 开头 --- [nio-8090-exec-4] org.freelancing.utils.JwtRequestFilter : JWT Token 不以 Bearer String 开头

我认为它会在这个区块中进行

@Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
                                    FilterChain chain)
        throws ServletException,
        IOException
    
        final String requestTokenHeader = request.getHeader("Authorization");
        String username = null;
        String jwtToken = null;
        // JWT Token is in the form "Bearer token". Remove Bearer word and get
        // only the Token
        if (requestTokenHeader != null && requestTokenHeader.startsWith("Bearer "))
        
            jwtToken = requestTokenHeader.substring(7);
            try
            
                username = jwtTokenUtil.getUsernameFromToken(jwtToken);
            
            catch (IllegalArgumentException e)
            
                System.out.println("Unable to get JWT Token");
            
            catch (ExpiredJwtException e)
            
                System.out.println("JWT Token has expired");
            
        
        else
        
            logger.warn("JWT Token does not begin with Bearer String");
        
        // Once we get the token validate it.
        if (username != null && SecurityContextHolder.getContext().getAuthentication() == null)
        
            UserDetails userDetails = this.jwtUserDetailsService.loadUserByUsername(username);
            // if token is valid configure Spring Security to manually set
            // authentication
            if (jwtTokenUtil.validateToken(jwtToken, userDetails))
            
                UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken =
                    new UsernamePasswordAuthenticationToken(userDetails, null,
                                                            userDetails.getAuthorities());
                usernamePasswordAuthenticationToken
                    .setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                // After setting the Authentication in the context, we specify
                // that the current user is authenticated. So it passes the
                // Spring Security Configurations successfully.
                SecurityContextHolder.getContext()
                    .setAuthentication(usernamePasswordAuthenticationToken);
            
        
        chain.doFilter(request, response);
    

我需要的是呈现登录页面,然后获取凭据并创建标题。但即使在点击 localhost:8090/login 时,它也会在上面的代码中要求标题,因为标题为空,这就是我收到错误:

JWT Token 不以 Bearer String 开头

登录组件

<div class="container">
  <div>
    User Name : <input type="text" name="username" [(ngModel)]="username">
    Password : <input type="password" name="password" [(ngModel)]="password">
  </div>
  <button (click)=checkLogin() class="btn btn-success">
    Login
  </button>
</div>

刚接触安全知识,请帮忙

【问题讨论】:

检查,当您在 Angular 应用程序中调用“localhost:8090/login”时,LoginComponent 正在向您的后端请求路由“/login”。 不,它正在渲染用户名和密码字段 【参考方案1】:

我假设您的 Angular 应用程序在调用它时根本不会显示。您不应尝试在同一台机器上的同一端口上运行两个不同的服务,因为您的浏览器将无法区分哪个服务应该获取您的请求。

目前,您正在向您的 API (URL:*/login) 发送一个 GET 请求,您可能没有设置。因此,您将在错误消息中收到 404,但您希望将请求定向到您的 Angular 应用程序以显示您的应用程序(例如登录掩码)。

【讨论】:

我们可以在同一个端口上使用 Angular 8 和 springboot,但是对于 Angular 中的路由和 springboot 控制器中的 URL,URL 应该不同 请说明您是通过 Spring Boot 部署 Angular 应用程序还是两者都是独立的服务。在后一种情况下,您不想指定相同的端口。 部署在同一个端口。供参考devglan.com/spring-boot/spring-boot-angular-deployment

以上是关于Spring Boot 安全性:在 Angular 8 中显示登录页面时出现问题的主要内容,如果未能解决你的问题,请参考以下文章

如何处理 Spring Boot Angular 应用程序安全性

Angular 2 + CORS + 带有 Spring Security 的 Spring Boot Rest Controller

如何使用 Spring Boot 和 Angular 应用程序隐藏授权标头

带有spring-boot安全休息api的角度2

CORS 起源问题 - Spring Boot 和 Angular 4

Spring Boot 提供被安全阻止的静态内容