mall整合SpringSecurity及JWT认证授权实战下

目录
  • 摘要
  • 登录注册功能实现
    • 添加UmsAdminController类
    • 添加UmsAdminService接口
    • 添加UmsAdminServiceImpl类
    • 修改Swagger的配置
    • 给PmsBrandController接口中的方法添加访问权限
  • 认证与授权流程演示
    • 运行项目,访问API
    • 未登录前访问接口
    • 登录后访问接口
    • 访问需要权限的接口
    • 改用其他有权限的帐号登录

摘要

接上一篇,controller和service层的代码实现及登录授权流程演示。

登录注册功能实现

添加UmsAdminController类

实现了后台用户登录、注册及获取权限的接口

package com.macro.mall.tiny.controller;
import com.macro.mall.tiny.common.api.CommonResult;
import com.macro.mall.tiny.dto.UmsAdminLoginParam;
import com.macro.mall.tiny.mbg.model.UmsAdmin;
import com.macro.mall.tiny.mbg.model.UmsPermission;
import com.macro.mall.tiny.service.UmsAdminService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
 * 后台用户管理
 * Created by macro on 2018/4/26.
 */
@Controller
@Api(tags = "UmsAdminController", description = "后台用户管理")
@RequestMapping("/admin")
public class UmsAdminController {
    @Autowired
    private UmsAdminService adminService;
    @Value("${jwt.tokenHeader}")
    private String tokenHeader;
    @Value("${jwt.tokenHead}")
    private String tokenHead;
    @ApiOperation(value = "用户注册")
    @RequestMapping(value = "/register", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult<UmsAdmin> register(@RequestBody UmsAdmin umsAdminParam, BindingResult result) {
        UmsAdmin umsAdmin = adminService.register(umsAdminParam);
        if (umsAdmin == null) {
            CommonResult.failed();
        }
        return CommonResult.success(umsAdmin);
    }
    @ApiOperation(value = "登录以后返回token")
    @RequestMapping(value = "/login", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult login(@RequestBody UmsAdminLoginParam umsAdminLoginParam, BindingResult result) {
        String token = adminService.login(umsAdminLoginParam.getUsername(), umsAdminLoginParam.getPassword());
        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("获取用户所有权限(包括+-权限)")
    @RequestMapping(value = "/permission/{adminId}", method = RequestMethod.GET)
    @ResponseBody
    public CommonResult<List<UmsPermission>> getPermissionList(@PathVariable Long adminId) {
        List<UmsPermission> permissionList = adminService.getPermissionList(adminId);
        return CommonResult.success(permissionList);
    }
}

添加UmsAdminService接口

package com.macro.mall.tiny.service;
import com.macro.mall.tiny.mbg.model.UmsAdmin;
import com.macro.mall.tiny.mbg.model.UmsPermission;
import java.util.List;
/**
 * 后台管理员Service
 * Created by macro on 2018/4/26.
 */
public interface UmsAdminService {
    /**
     * 根据用户名获取后台管理员
     */
    UmsAdmin getAdminByUsername(String username);
    /**
     * 注册功能
     */
    UmsAdmin register(UmsAdmin umsAdminParam);
    /**
     * 登录功能
     * @param username 用户名
     * @param password 密码
     * @return 生成的JWT的token
     */
    String login(String username, String password);
    /**
     * 获取用户所有权限(包括角色权限和+-权限)
     */
    List<UmsPermission> getPermissionList(Long adminId);
}

添加UmsAdminServiceImpl类

package com.macro.mall.tiny.service.impl;
import com.macro.mall.tiny.common.utils.JwtTokenUtil;
import com.macro.mall.tiny.dao.UmsAdminRoleRelationDao;
import com.macro.mall.tiny.dto.UmsAdminLoginParam;
import com.macro.mall.tiny.mbg.mapper.UmsAdminMapper;
import com.macro.mall.tiny.mbg.model.UmsAdmin;
import com.macro.mall.tiny.mbg.model.UmsAdminExample;
import com.macro.mall.tiny.mbg.model.UmsPermission;
import com.macro.mall.tiny.service.UmsAdminService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.List;
/**
 * UmsAdminService实现类
 * Created by macro on 2018/4/26.
 */
@Service
public class UmsAdminServiceImpl implements UmsAdminService {
    private static final Logger LOGGER = LoggerFactory.getLogger(UmsAdminServiceImpl.class);
    @Autowired
    private UserDetailsService userDetailsService;
    @Autowired
    private JwtTokenUtil jwtTokenUtil;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Value("${jwt.tokenHead}")
    private String tokenHead;
    @Autowired
    private UmsAdminMapper adminMapper;
    @Autowired
    private UmsAdminRoleRelationDao adminRoleRelationDao;
    @Override
    public UmsAdmin getAdminByUsername(String username) {
        UmsAdminExample example = new UmsAdminExample();
        example.createCriteria().andUsernameEqualTo(username);
        List<UmsAdmin> adminList = adminMapper.selectByExample(example);
        if (adminList != null && adminList.size() > 0) {
            return adminList.get(0);
        }
        return null;
    }
    @Override
    public UmsAdmin register(UmsAdmin umsAdminParam) {
        UmsAdmin umsAdmin = new UmsAdmin();
        BeanUtils.copyProperties(umsAdminParam, umsAdmin);
        umsAdmin.setCreateTime(new Date());
        umsAdmin.setStatus(1);
        //查询是否有相同用户名的用户
        UmsAdminExample example = new UmsAdminExample();
        example.createCriteria().andUsernameEqualTo(umsAdmin.getUsername());
        List<UmsAdmin> umsAdminList = adminMapper.selectByExample(example);
        if (umsAdminList.size() > 0) {
            return null;
        }
        //将密码进行加密操作
        String encodePassword = passwordEncoder.encode(umsAdmin.getPassword());
        umsAdmin.setPassword(encodePassword);
        adminMapper.insert(umsAdmin);
        return umsAdmin;
    }
    @Override
    public String login(String username, String password) {
        String token = null;
        try {
            UserDetails userDetails = userDetailsService.loadUserByUsername(username);
            if (!passwordEncoder.matches(password, userDetails.getPassword())) {
                throw new BadCredentialsException("密码不正确");
            }
            UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
            SecurityContextHolder.getContext().setAuthentication(authentication);
            token = jwtTokenUtil.generateToken(userDetails);
        } catch (AuthenticationException e) {
            LOGGER.warn("登录异常:{}", e.getMessage());
        }
        return token;
    }
    @Override
    public List<UmsPermission> getPermissionList(Long adminId) {
        return adminRoleRelationDao.getPermissionList(adminId);
    }
}

修改Swagger的配置

通过修改配置实现调用接口自带Authorization头,这样就可以访问需要登录的接口了。

package com.macro.mall.tiny.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.ApiKey;
import springfox.documentation.service.AuthorizationScope;
import springfox.documentation.service.SecurityReference;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import java.util.ArrayList;
import java.util.List;
/**
 * Swagger2API文档的配置
 */
@Configuration
@EnableSwagger2
public class Swagger2Config {
    @Bean
    public Docket createRestApi(){
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .select()
                //为当前包下controller生成API文档
                .apis(RequestHandlerSelectors.basePackage("com.macro.mall.tiny.controller"))
                .paths(PathSelectors.any())
                .build()
                //添加登录认证
                .securitySchemes(securitySchemes())
                .securityContexts(securityContexts());
    }
    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("SwaggerUI演示")
                .description("mall-tiny")
                .contact("macro")
                .version("1.0")
                .build();
    }
    private List&lt;ApiKey&gt; securitySchemes() {
        //设置请求头信息
        List&lt;ApiKey&gt; result = new ArrayList&lt;&gt;();
        ApiKey apiKey = new ApiKey("Authorization", "Authorization", "header");
        result.add(apiKey);
        return result;
    }
    private List&lt;SecurityContext&gt; securityContexts() {
        //设置需要登录认证的路径
        List&lt;SecurityContext&gt; result = new ArrayList&lt;&gt;();
        result.add(getContextByPath("/brand/.*"));
        return result;
    }
    private SecurityContext getContextByPath(String pathRegex){
        return SecurityContext.builder()
                .securityReferences(defaultAuth())
                .forPaths(PathSelectors.regex(pathRegex))
                .build();
    }
    private List&lt;SecurityReference&gt; defaultAuth() {
        List&lt;SecurityReference&gt; result = new ArrayList&lt;&gt;();
        AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
        AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
        authorizationScopes[0] = authorizationScope;
        result.add(new SecurityReference("Authorization", authorizationScopes));
        return result;
    }
}

给PmsBrandController接口中的方法添加访问权限

  • 给查询接口添加pms:brand:read权限
  • 给修改接口添加pms:brand:update权限
  • 给删除接口添加pms:brand:delete权限
  • 给添加接口添加pms:brand:create权限

例子:

@PreAuthorize("hasAuthority('pms:brand:read')")
public CommonResult<List<PmsBrand>> getBrandList() {
    return CommonResult.success(brandService.listAllBrand());
}

认证与授权流程演示

运行项目,访问API

Swagger api地址:http://localhost:8080/swagger-ui.html

未登录前访问接口

登录后访问接口

进行登录操作:登录帐号test 123456

点击Authorize按钮,在弹框中输入登录接口中获取到的token信息

登录后访问获取权限列表接口,发现已经可以正常访问

访问需要权限的接口

由于test帐号并没有设置任何权限,所以他无法访问具有pms:brand:read权限的获取品牌列表接口。

改用其他有权限的帐号登录

改用admin 123456登录后访问,点击Authorize按钮打开弹框,点击logout登出后再重新输入新token。

项目源码地址github.com/macrozheng/…

mall持续更新地址:https://github.com/macrozheng/mall

以上就是mall整合SpringSecurity及JWT认证授权实战下的详细内容,更多关于mall整合SpringSecurity JWT的资料请关注我们其它相关文章!

(0)

相关推荐

  • springboot+jwt+springSecurity微信小程序授权登录问题

    场景重现:1.微信小程序向后台发送请求 --而后台web采用的springSecuriry没有token生成,就会拦截请求,,所以小编记录下这个问题 微信小程序授权登录问题 思路 参考网上一大堆资料 核心关键字: 自定义授权+鉴权 (说的通俗就是解决办法就是改造springSecurity的过滤器) 参考文章 https://www.jb51.net/article/204704.htm 总的来说的 通过自定义的WxAppletAuthenticationFilter替换默认的UsernameP

  • mall整合SpringSecurity及JWT实现认证授权实战

    目录 摘要 项目使用框架介绍 SpringSecurity JWT JWT的组成 JWT实例 JWT实现认证和授权的原理 Hutool 项目使用表说明 整合SpringSecurity及JWT 在pom.xml中添加项目依赖 添加JWT token的工具类 添加SpringSecurity的配置类 相关依赖及方法说明 添加RestfulAccessDeniedHandler 添加RestAuthenticationEntryPoint 添加AdminUserDetails 添加JwtAuthen

  • SpringSecurity+JWT实现前后端分离的使用详解

    创建一个配置类 SecurityConfig 继承 WebSecurityConfigurerAdapter package top.ryzeyang.demo.common.config; import org.springframework.context.annotation.Bean; import org.springframework.security.access.hierarchicalroles.RoleHierarchy; import org.springframework

  • SpringSecurity Jwt Token 自动刷新的实现

    功能需求 最近项目中有这么一个功能,用户登录系统后,需要给 用户 颁发一个 token ,后续访问系统的请求都需要带上这个 token ,如果请求没有带上这个 token 或者 token 过期了,那么禁止访问系统.如果用户一直访问系统,那么还需要自动延长 token 的过期时间. 功能分析 1.token 的生成 使用现在比较流行的 jwt 来生成. 2.token 的自动延长 要实现 token 的自动延长,系统给用户 颁发 一个 token 无法实现,那么通过变通一个,给用户生成 2个 t

  • SpringSecurity整合jwt权限认证的全流程讲解

    JWT 本文代码截取自实际项目. jwt(Json Web Token),一个token,令牌. 简单流程: 用户登录成功后,后端返回一个token,也就是颁发给用户一个凭证.之后每一次访问,前端都需要携带这个token,后端通过token来解析出当前访问对象. 优点 1.一定程度上解放了后端,后端不需要再记录当前用户是谁,不需要再维护一个session,节省了开销. 2.session依赖于cookie,某些场合cookie是用不了的,比如用户浏览器cookie被禁用.移动端无法存储cooki

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

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

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

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

  • mall整合SpringSecurity及JWT认证授权实战下

    目录 摘要 登录注册功能实现 添加UmsAdminController类 添加UmsAdminService接口 添加UmsAdminServiceImpl类 修改Swagger的配置 给PmsBrandController接口中的方法添加访问权限 认证与授权流程演示 运行项目,访问API 未登录前访问接口 登录后访问接口 访问需要权限的接口 改用其他有权限的帐号登录 摘要 接上一篇,controller和service层的代码实现及登录授权流程演示. 登录注册功能实现 添加UmsAdminCo

  • SpringBoot整合SpringSecurity实现JWT认证的项目实践

    目录 前言 1.创建SpringBoot工程 2.导入SpringSecurity与JWT的相关依赖 3.定义SpringSecurity需要的基础处理类 4. 构建JWT token工具类 5.实现token验证的过滤器 6. SpringSecurity的关键配置 7. 编写Controller进行测试 前言 微服务架构,前后端分离目前已成为互联网项目开发的业界标准,其核心思想就是前端(APP.小程序.H5页面等)通过调用后端的API接口,提交及返回JSON数据进行交互.在前后端分离项目中,

  • ASP.NET Core学习之使用JWT认证授权详解

    概述 认证授权是很多系统的基本功能 , 在以前PC的时代 , 通常是基于cookies-session这样的方式实现认证授权 , 在那个时候通常系统的用户量都不会很大, 所以这种方式也一直很好运行, 随着现在都软件用户量越来越大, 系统架构也从以前垂直扩展(增加服务器性能) -> 水平扩展(增加服务器数量) cookies-session 工作方式 客户端提交用户信息 -> 服务器识别用户 -> 服务端保存用户信息 -> 返回session-id客户端 -> 客户端保存ses

  • ASP.NET Core使用JWT认证授权的方法

    demo地址: https://github.com/william0705/JWTS 名词解析 认证 : 识别用户是否合法 授权: 赋予用户权限 (能访问哪些资源) 鉴权: 鉴定权限是否合法 Jwt优势与劣势 优势 1. 无状态 token 存储身份验证所有信息 , 服务端不需要保存用户身份验证信息, 减少服务端压力 , 服务端更容易水平扩展, 由于无状态, 又会导致它最大缺点 , 很难注销 2. 支持跨域访问 Cookie是不允许垮域访问的,token支持 3. 跨语言 基于标准化的 JSO

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

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

  • asp.net core3.1cookie和jwt混合认证授权实现多种身份验证方案

    目录 认证授权 身份认证 授权 默认授权 选择授权 总结 开发了一个公司内部系统,使用asp.net core 3.1.在开发用户认证授权使用的是简单的cookie认证方式,然后开发好了要写几个接口给其它系统调用数据.并且只是几个简单的接口不准备再重新部署一个站点,所以就直接在MVC的项目里面加了一个API区域用来写接口.这时候因为是接口所以就不能用cookie方式进行认证,得加一个jwt认证,采用多种身份验证方案来进行认证授权. 认证授权 身份验证是确定用户身份的过程. 授权是确定用户是否有权

  • ASP.NET Core 6.0 添加 JWT 认证和授权功能

    目录 序言 相关名词 认证(Authentication) 基本步骤 1 安装 Nuget 包 2 准备配置信息 3 添加服务 4 调用中间件 5 JwtHelper 类实现 6 控制器配置 7 测试调用 授权(Authorization) 相关标签(Attribute) 授权方式 1 Policy(策略) 2 Role(角色) 3 Scheme(方案) 3 定义权限项 4 实现 Requirement 5 实现授权处理程序 Handler 6 添加授权处理程序 7 添加授权策略 8 控制器配置

  • 基于springboot实现整合shiro实现登录认证以及授权过程解析

    这篇文章主要介绍了基于springboot实现整合shiro实现登录认证以及授权过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 1.添加shiro的依赖 <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring-boot-web- starter</artifactId> <version&g

随机推荐