Java SpringSecurity+JWT实现登录认证

目录
  • 整合步骤
  • 实现原理
    • 目录结构
    • 做了哪些变化

前言:

学习过我的mall项目的应该知道,mall-admin模块是使用SpringSecurity+JWT来实现登录认证的,而mall-portal模块是使用的SpringSecurity基于Session的默认机制来实现登陆认证的。很多小伙伴都找不到mall-portal的登录接口,最近我把这两个模块的登录认证给统一了,都使用SpringSecurity+JWT的形式实现。主要是通过把登录认证的通用逻辑抽取到了mall-security模块来实现的,下面我们讲讲如何使用mall-security模块来实现登录认证,仅需四步即可。

整合步骤

这里我们以mall-portal改造为例来说说如何实现。

第一步,给需要登录认证的模块添加mall-security依赖:

<dependency>
    <groupId>com.macro.mall</groupId>
    <artifactId>mall-security</artifactId>
</dependency>

第二步,添加MallSecurityConfig配置类,继承mall-security中的SecurityConfig配置,并且配置一个UserDetailsService接口的实现类,用于获取登录用户详情:

/**
 * mall-security模块相关配置
 * Created by macro on 2019/11/5.
 */
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled=true)
publicclass MallSecurityConfig extends SecurityConfig {
    @Autowired
    private UmsMemberService memberService;

    @Bean
    public UserDetailsService userDetailsService() {
        //获取登录用户信息
        return username -> memberService.loadUserByUsername(username);
    }
}

第三步,在application.yml中配置下不需要安全保护的资源路径:

secure:
  ignored:
    urls:#安全路径白名单
      -/swagger-ui.html
      -/swagger-resources/**
      -/swagger/**
      -/**/v2/api-docs
      -/**/*.js
      -/**/*.css
      -/**/*.png
      -/**/*.ico
      -/webjars/springfox-swagger-ui/**
      -/druid/**
      -/actuator/**
      -/sso/**
      -/home/**

第四步,在UmsMemberController中实现登录和刷新token的接口:

/**
 * 会员登录注册管理Controller
 * Created by macro on 2018/8/3.
 */
@Controller
@Api(tags = "UmsMemberController", description = "会员登录注册管理")
@RequestMapping("/sso")
publicclass UmsMemberController {
    @Value("${jwt.tokenHeader}")
    private String tokenHeader;
    @Value("${jwt.tokenHead}")
    private String tokenHead;
    @Autowired
    private UmsMemberService memberService;

    @ApiOperation("会员登录")
    @RequestMapping(value = "/login", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult login(@RequestParam String username,
                              @RequestParam String password) {
        String token = memberService.login(username, password);
        if (token == null) {
            return CommonResult.validateFailed("用户名或密码错误");
        }
        Map<String, String> tokenMap = new HashMap<>();
        tokenMap.put("token", token);
        tokenMap.put("tokenHead", tokenHead);
        return CommonResult.success(tokenMap);
    }

    @ApiOperation(value = "刷新token")
    @RequestMapping(value = "/refreshToken", method = RequestMethod.GET)
    @ResponseBody
    public CommonResult refreshToken(HttpServletRequest request) {
        String token = request.getHeader(tokenHeader);
        String refreshToken = memberService.refreshToken(token);
        if (refreshToken == null) {
            return CommonResult.failed("token已经过期!");
        }
        Map<String, String> tokenMap = new HashMap<>();
        tokenMap.put("token", refreshToken);
        tokenMap.put("tokenHead", tokenHead);
        return CommonResult.success(tokenMap);
    }
}

实现原理

将SpringSecurity+JWT的代码封装成通用模块后,就可以方便其他需要登录认证的模块来使用,下面我们来看看它是如何实现的,首先我们看下mall-security的目录结构。

目录结构

mall-security
├── component
|    ├── JwtAuthenticationTokenFilter -- JWT登录授权过滤器
|    ├── RestAuthenticationEntryPoint -- 自定义返回结果:未登录或登录过期
|    └── RestfulAccessDeniedHandler -- 自定义返回结果:没有权限访问时
├── config
|    ├── IgnoreUrlsConfig -- 用于配置不需要安全保护的资源路径
|    └── SecurityConfig -- SpringSecurity通用配置
└── util
     └── JwtTokenUtil -- JWT的token处理工具类

做了哪些变化

其实我也就添加了两个类,一个IgnoreUrlsConfig,用于从application.yml中获取不需要安全保护的资源路径。一个SecurityConfig提取了一些SpringSecurity的通用配置。

IgnoreUrlsConfig中的代码:

/**
 * 用于配置不需要保护的资源路径
 * Created by macro on 2018/11/5.
 */
@Getter
@Setter
@ConfigurationProperties(prefix = "secure.ignored")
publicclass IgnoreUrlsConfig {

    private List<String> urls = new ArrayList<>();

}

SecurityConfig中的代码:

/**
 * 对SpringSecurity的配置的扩展,支持自定义白名单资源路径和查询用户逻辑
 * Created by macro on 2019/11/5.
 */
publicclass SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
        ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry = httpSecurity
                .authorizeRequests();
        //不需要保护的资源路径允许访问
        for (String url : ignoreUrlsConfig().getUrls()) {
            registry.antMatchers(url).permitAll();
        }
        //允许跨域请求的OPTIONS请求
        registry.antMatchers(HttpMethod.OPTIONS)
                .permitAll();
        // 任何请求需要身份认证
        registry.and()
                .authorizeRequests()
                .anyRequest()
                .authenticated()
                // 关闭跨站请求防护及不使用session
                .and()
                .csrf()
                .disable()
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                // 自定义权限拒绝处理类
                .and()
                .exceptionHandling()
                .accessDeniedHandler(restfulAccessDeniedHandler())
                .authenticationEntryPoint(restAuthenticationEntryPoint())
                // 自定义权限拦截器JWT过滤器
                .and()
                .addFilterBefore(jwtAuthenticationTokenFilter(), UsernamePasswordAuthenticationFilter.class);
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService())
                .passwordEncoder(passwordEncoder());
    }
    @Bean
    public PasswordEncoder passwordEncoder() {
        returnnew BCryptPasswordEncoder();
    }
    @Bean
    public JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter() {
        returnnew JwtAuthenticationTokenFilter();
    }
    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        returnsuper.authenticationManagerBean();
    }
    @Bean
    public RestfulAccessDeniedHandler restfulAccessDeniedHandler() {
        returnnew RestfulAccessDeniedHandler();
    }
    @Bean
    public RestAuthenticationEntryPoint restAuthenticationEntryPoint() {
        returnnew RestAuthenticationEntryPoint();
    }
    @Bean
    public IgnoreUrlsConfig ignoreUrlsConfig() {
        returnnew IgnoreUrlsConfig();
    }
    @Bean
    public JwtTokenUtil jwtTokenUtil() {
        returnnew JwtTokenUtil();
    }
}

到此这篇关于Java SpringSecurity+JWT实现登录认证 的文章就介绍到这了,更多相关Java SpringSecurity 内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • JavaWeb使用Session和Cookie实现登录认证

    后台管理页面往往需要登录才可以进行操作,这时就需要Seession来记录登录状态 要实现起来也是非常简单,只需要自定义一个HandlerInterceptor就行了 自定义的HandlerInterceptor也只有短短几行代码 public class LoginInterceptor implements HandlerInterceptor { @Override public void afterCompletion(HttpServletRequest request, HttpSer

  • Java Jwt库的简介及使用详解

    JWT介绍 JWT概念 JWT , 全写JSON Web Token, 是开放的行业标准RFC7591,用来实现端到端安全验证. 简单来说, 就是通过一些算法对加密字符串和JSON对象之间进行加解密. JWT加密JSON,保存在客户端,不需要在服务端保存会话信息.,可以应用在前后端分离的用户验证上,后端对前端输入的用户信息进行加密产生一个令牌字符串, 前端再次请求时附加此字符串,后端再使用算法解密. JWT流程: JWT的构成 JWT字符串: 一段加密的JSON字符串. 包含了三类信息 Head

  • Java中SpringSecurity密码错误5次锁定用户的实现方法

    Spring Security简介 Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架.它提供了一组可以在Spring应用上下文中配置的Bean,充分利用了Spring IoC,DI(控制反转Inversion of Control ,DI:Dependency Injection 依赖注入)和AOP(面向切面编程)功能,为应用系统提供声明式的安全访问控制功能,减少了为企业系统安全控制编写大量重复代码的工作. 下面看下实例代码: 第

  • Java使用OTP动态口令(每分钟变一次)进行登录认证

    GIT地址:https://github.com/suyin58/otp-demo 动态码截图: 在对外网开放的后台管理系统中,使用静态口令进行身份验证可能会存在如下问题: (1) 为了便于记忆,用户多选择有特征作为密码,所有静态口令相比动态口令而言,容易被猜测和破解: (2) 黑客可以从网上或电话线上截获静态密码,如果是非加密方式传输,用户认证信息可被轻易获取: (3) 内部工作人员可通过合法授权取得用户密码而非法使用: 静态口令根本上不能确定用户的身份,其结果是,个人可以轻松地伪造一个假身份

  • Java JWT实现跨域身份验证方法详解

    目录 1.JWT简介 2.JWT的结构 2.1 头部(header) 2.2 载荷(payload) 2.3 签证(signature) 3.JWT的原则 4.JWT的用法 5.JWT的问题和趋势 6.整合JWT令牌 6.1 在模块中添加jwt工具依赖 6.2 创建JWT工具类 1.JWT简介 JWT(JSON Web Token)是目前流行的跨域认证解决方案,是一个开放标准(RFC 7519),它定义了一种紧凑的.自包含的方式,用于作为JSON对象在各方之间安全地传输信息.该信息可以被验证和信

  • 在Java中使用Jwt的示例代码

    JWT 特点 JWT 默认是不加密,但也是可以加密的.生成原始 Token 以后,可以用密钥再加密一次. JWT 不加密的情况下,不能将秘密数据写入 JWT. JWT 不仅可以用于认证,也可以用于交换信息.有效使用 JWT,可以降低服务器查询数据库的次数. JWT 的最大缺点是,由于服务器不保存 session 状态,因此无法在使用过程中废止某个 token,或者更改 token 的权限.也就是说,一旦 JWT 签发了,在到期之前就会始终有效,除非服务器部署额外的逻辑. JWT 本身包含了认证信

  • 基于Java验证jwt token代码实例

    这篇文章主要介绍了基于Java验证jwt token代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 How to load public certificate from pem file..?地址 1.HS256对称加密 package jwt; import java.io.FileInputStream; import java.io.IOException; import java.security.KeyFactory; im

  • 详解springSecurity之java配置篇

    一 前言 本篇是springSecurity知识的入门第二篇,主要内容是如何使用java配置的方式进行配置springSeciruty,然后通过一个简单的示例自定义登陆页面,覆盖原有springSecurity默认的登陆页面:学习这篇的基础是 知识追寻者之前发布 过 的<springSecurity入门篇> 二 java配置 2.1配置账号密码 如下所示, 使用 @EnableWebSecurity 在配置类上开启security配置功能: 在配置类中定义bean 名为 UserDetails

  • Java中使用JWT生成Token进行接口鉴权实现方法

    先介绍下利用JWT进行鉴权的思路: 1.用户发起登录请求. 2.服务端创建一个加密后的JWT信息,作为Token返回. 3.在后续请求中JWT信息作为请求头,发给服务端. 4.服务端拿到JWT之后进行解密,正确解密表示此次请求合法,验证通过:解密失败说明Token无效或者已过期. 流程图如下: 一.用户发起登录请求 二.服务端创建一个加密后的JWT信息,作为Token返回 1.用户登录之后把生成的Token返回给前端 @Authorization @ResponseBody @GetMappin

  • Java SpringSecurity+JWT实现登录认证

    目录 整合步骤 实现原理 目录结构 做了哪些变化 前言: 学习过我的mall项目的应该知道,mall-admin模块是使用SpringSecurity+JWT来实现登录认证的,而mall-portal模块是使用的SpringSecurity基于Session的默认机制来实现登陆认证的.很多小伙伴都找不到mall-portal的登录接口,最近我把这两个模块的登录认证给统一了,都使用SpringSecurity+JWT的形式实现.主要是通过把登录认证的通用逻辑抽取到了mall-security模块来

  • SpringSecurity构建基于JWT的登录认证实现

    最近项目的登录验证部分,采用了 JWT 验证的方式.并且既然采用了 Spring Boot 框架,验证和权限管理这部分,就自然用了 Spring Security.这里记录一下具体实现. 在项目采用 JWT 方案前,有必要先了解它的特性和适用场景,毕竟软件工程里,没有银弹.只有合适的场景,没有万精油的方案. 一言以蔽之,JWT 可以携带非敏感信息,并具有不可篡改性.可以通过验证是否被篡改,以及读取信息内容,完成网络认证的三个问题:"你是谁"."你有哪些权限".&qu

  • SpringBoot+SpringSecurity+JWT实现系统认证与授权示例

    目录 1. Spring Security简介 2. JWT简介 3. Spring Boot整合Spring Security 4. 配置Spring Security使用JWT认证 5. 实现登录接口 6. 测试 7. 源码 1. Spring Security简介 Spring Security是Spring的一个核心项目,它是一个功能强大且高度可定制的认证和访问控制框架.它提供了认证和授权功能以及抵御常见的攻击,它已经成为保护基于spring的应用程序的事实标准. Spring Boot

  • AntDesign Pro + .NET Core 实现基于JWT的登录认证功能

    很多同学说AgileConfig的UI实在是太丑了.我想想也是的,本来这个项目是我自己使用的,一开始甚至连UI都没有,全靠手动在数据库里修改数据.后来加上了UI也是使用了老掉牙的bootstrap3做为基础样式.前台框架也是使用了angularjs,同样是老掉牙的东西.过年期间终于下决心翻新AgileConfig的前端UI.最后选择的前端UI框架为AntDesign Pro + React.至于为啥选Ant-Design Pro是因为他好看,而且流行,选择React是因为VUE跟Angular我

  • Spring Security 自定义短信登录认证的实现

    自定义登录filter 上篇文章我们说到,对于用户的登录,security通过定义一个filter拦截login路径来实现的,所以我们要实现自定义登录,需要自己定义一个filter,继承AbstractAuthenticationProcessingFilter,从request中提取到手机号和验证码,然后提交给AuthenticationManager: public class SmsAuthenticationFilter extends AbstractAuthenticationPro

  • Springboot+SpringSecurity+JWT实现用户登录和权限认证示例

    如今,互联网项目对于安全的要求越来越严格,这就是对后端开发提出了更多的要求,目前比较成熟的几种大家比较熟悉的模式,像RBAC 基于角色权限的验证,shiro框架专门用于处理权限方面的,另一个比较流行的后端框架是Spring-Security,该框架提供了一整套比较成熟,也很完整的机制用于处理各类场景下的可以基于权限,资源路径,以及授权方面的解决方案,部分模块支持定制化,而且在和oauth2.0进行了很好的无缝连接,在移动互联网的授权认证方面有很强的优势,具体的使用大家可以结合自己的业务场景进行选

  • Vue+Jwt+SpringBoot+Ldap完成登录认证的示例代码

    本人野生程序员一名,了解了一些微服务架构.前后端分离.SPA的知识后就想试试做点什么东西.之前一直做后端,前端只是有基础知识.之前学习过angularjs,但当时就是一脸懵逼(完全看不懂是啥)就放弃了.最近又学了Vue,这次感觉总算明白了一些,但其中也跳过很多坑(应该还会更多),在这里写下来记录一下吧. 说回主题,之前传统登录认证的方法基本是由服务器端提供一个登录页面,页面中的一个form输入username和password后POST给服务器,服务器将这些信息与DB或Ldap中的用户信息对比,

  • 解析SpringSecurity+JWT认证流程实现

    纸上得来终觉浅,觉知此事要躬行. 楔子 本文适合:对Spring Security有一点了解或者跑过简单demo但是对整体运行流程不明白的同学,对SpringSecurity有兴趣的也可以当作你们的入门教程,示例代码中也有很多注释. 本文代码:码云地址  GitHub地址 大家在做系统的时候,一般做的第一个模块就是认证与授权模块,因为这是一个系统的入口,也是一个系统最重要最基础的一环,在认证与授权服务设计搭建好了之后,剩下的模块才得以安全访问. 市面上一般做认证授权的框架就是shiro和Spri

  • SpringBoot+Vue+JWT的前后端分离登录认证详细步骤

    前后端分离的概念在现在很火,最近也学习了一下前后端分离的登录认证. 创建后端springboot工程 这个很简单了,按照idea的一步一步创建就行 文件目录结构: pom文件依赖导入. <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </

  • PHP实现JWT的Token登录认证

    1.JWT简介 JSON Web Token(缩写 JWT),是目前最流行的跨域认证解决方案. session登录认证方案:用户从客户端传递用户名.密码等信息,服务端认证后将信息存储在session中,将session_id放到cookie中. 以后访问其他页面,自动从cookie中取到session_id,再从session中取认证信息. 另一类解决方案,将认证信息,返回给客户端,存储到客户端.下次访问其他页面,需要从客户端传递认证信息回服务端. JWT就是这类方案的代表,将认证信息保存在客户

随机推荐