栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

混合身份验证-基于Spring MVC会话+基于JWT令牌

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

混合身份验证-基于Spring MVC会话+基于JWT令牌

是否有可能在同一项目中同时使用两种身份验证。

是的你可以。通过具有两个身份验证处理过滤器。

过滤器-1 :用于Rest
API(JwtAuthTokenFilter),该API应该是无状态的,并由每次请求中发送的Authorization令牌标识。
过滤器2
:您需要另一个过滤器(UsernamePasswordAuthenticationFilter)默认情况下,如果通过进行配置,spring-
security将提供此过滤器

http.formLogin()
。在这里,每个请求都由
JSESSIONID
关联的session(cookie)标识。如果请求中不包含有效的会话,则它将被重定向到身份验证入口点(例如:login-
page)。

推荐的网址格式

api-url-pattern    = "/api/**"webApp-url-pattern = "/**"

怎么运行的

  • URL的

    /api/**
    将会通过
    JwtAuthTokenFilter
    它将读取令牌的地方传递,如果它具有有效的令牌,则设置身份验证对象,并继续进行链接。如果没有有效的请求,则链会断开,并且将以401(未授权)状态发送响应。

  • URL以外的其他

    /api/**
    将由
    UsernamePasswordAuthenticationFilter
    [将由
    .formLogin()
    配置配置的Spring Security中的默认值]处理。它将检查有效的会话,如果它不包含有效的会话,它将重定向到配置的logoutSuccessUrl。

注意: 您的Webapp无法使用现有会话访问API。您具有的选择是使用Jwt令牌从Web应用程序访问API。

如何配置

要实现两个不同的身份验证处理过滤器,您应该以不同的顺序配置多个http安全配置,
可以通过在安全配置类中声明静态类来配置多个http安全配置,如下所示。
(即使OP要求在概念上明智地将代码明智地呈现出来,也可能有助于您参考)

Spring安全配置

@Configuration@EnableWebSecurity@ComponentScan(basePackages = "com.gmail.nlpraveennl")public class SpringSecurityConfig{    @Bean    public PasswordEnprer passwordEnprer()     {        return new BCryptPasswordEnprer();    }    @Configuration    @Order(1)    public static class RestApiSecurityConfig extends WebSecurityConfigurerAdapter    {        @Autowired        private JwtAuthenticationTokenFilter jwtauthFilter;        @Override        protected void configure(HttpSecurity http) throws Exception        { http     .csrf().disable()     .antMatcher("/api/**")     .authorizeRequests()     .antMatchers("/api/authenticate").permitAll()     .antMatchers("/api/**").hasAnyRole("APIUSER") .and()     .addFilterBefore(jwtauthFilter, UsernamePasswordAuthenticationFilter.class); http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);        }    }    @Configuration    @Order(2)    public static class LoginFormSecurityConfig extends WebSecurityConfigurerAdapter    {        @Autowired        private PasswordEnprer passwordEnprer;        @Autowired        public void configureInMemoryAuthentication(AuthenticationManagerBuilder auth) throws Exception        { auth.inMemoryAuthentication().withUser("admin").password(passwordEnprer.enpre("admin@123#")).roles("ADMIN");        }        @Override        protected void configure(HttpSecurity http) throws Exception        { http     .csrf().disable()     .antMatcher("/**").authorizeRequests()     .antMatchers("/resources/**").permitAll()     .antMatchers("/**").hasRole("ADMIN") .and().formLogin(); http.sessionManagement().maximumSessions(1).expiredUrl("/customlogin?expired=true");        }    }}

JWT身份验证令牌过滤器

@Componentpublic class JwtAuthenticationTokenFilter extends OncePerRequestFilter{    @Autowired    private JwtTokenUtil jwtTokenUtil;    @Override    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException    {        final String header = request.getHeader("Authorization");        if (header != null && header.startsWith("Bearer "))         { String authToken = header.substring(7); System.out.println(authToken); try {     String username = jwtTokenUtil.getUsernameFromToken(authToken);     if (username != null && SecurityContextHolder.getContext().getAuthentication() == null)     {         if (jwtTokenUtil.validateToken(authToken, username))         {  List<GrantedAuthority> authList = new ArrayList<>();  authList.add(new SimpleGrantedAuthority("ROLE_APIUSER"));  UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(username, null, authList);  usernamePasswordAuthenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));  SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);         }     } } catch (Exception e) {     System.out.println("Unable to get JWT Token, possibly expired"); }        }        chain.doFilter(request, response);    }}

Jwt令牌util类

@Componentpublic class JwtTokenUtil implements Serializable{    private static final long   serialVersionUID    = 8544329907338151549L;    public static final long    JWT_TOKEN_VALIDITY  = 5 * 60 * 60;    private String   secret   = "my-secret";    public String getUsernameFromToken(String token)    {        return getClaimFromToken(token, Claims::getSubject);    }    public Date getExpirationDateFromToken(String token)    {        return getClaimFromToken(token, Claims::getExpiration);    }    public <T> T getClaimFromToken(String token, Function<Claims, T> claimsResolver)    {        final Claims claims = getAllClaimsFromToken(token);        return claimsResolver.apply(claims);    }    private Claims getAllClaimsFromToken(String token)    {        return Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();    }    private Boolean isTokenExpired(String token)    {        final Date expiration = getExpirationDateFromToken(token);        return expiration.before(new Date());    }    public String generateToken(String username)    {        Map<String, Object> claims = new HashMap<>();        return doGenerateToken(claims, username);    }    private String doGenerateToken(Map<String, Object> claims, String subject)    {        return "Bearer "+Jwts.builder().setClaims(claims).setSubject(subject).setIssuedAt(new Date(System.currentTimeMillis()))     .setExpiration(new Date(System.currentTimeMillis() + JWT_TOKEN_VALIDITY * 1000)).signWith(SignatureAlgorithm.HS512, secret).compact();    }    public Boolean validateToken(String token, String usernameFromToken)    {        final String username = getUsernameFromToken(token);        return (username.equals(usernameFromToken) && !isTokenExpired(token));    }}

分派器Servlet配置

@Configuration@EnableWebMvc@ComponentScan(basePackages = "com.gmail.nlpraveennl") //Do not skip componentscanpublic class ServletConfiguration implements WebMvcConfigurer{     @Bean     public ViewResolver configureViewResolver()      {         InternalResourceViewResolver viewResolve = new InternalResourceViewResolver();         viewResolve.setPrefix("/WEB-INF/jsp/");         viewResolve.setSuffix(".jsp");         return viewResolve;     }    @Bean    public ResourceBundleMessageSource messageSource()    {        ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();        messageSource.setbasename("messages");        messageSource.setDefaultEncoding("UTF-8");        messageSource.setUseCodeAsDefaultMessage(true);        return messageSource;    }    @Override    public void addResourceHandlers(ResourceHandlerRegistry registry)    {        registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");    }}


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/594822.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号