您的位置:首页 > 编程语言 > Java开发

mall整合SpringSecurity和JWT实现认证和授权(二)

2021-01-14 21:19 736 查看

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

登录注册功能实现

添加UmsAdminController类

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

  1. package com.macro.mall.tiny.controller;


  2. import com.macro.mall.tiny.common.api.CommonResult;

  3. import com.macro.mall.tiny.dto.UmsAdminLoginParam;

  4. import com.macro.mall.tiny.mbg.model.UmsAdmin;

  5. import com.macro.mall.tiny.mbg.model.UmsPermission;

  6. import com.macro.mall.tiny.service.UmsAdminService;

  7. import io.swagger.annotations.Api;

  8. import io.swagger.annotations.ApiOperation;

  9. import org.springframework.beans.factory.annotation.Autowired;

  10. import org.springframework.beans.factory.annotation.Value;

  11. import org.springframework.stereotype.Controller;

  12. import org.springframework.validation.BindingResult;

  13. import org.springframework.web.bind.annotation.*;


  14. import java.util.HashMap;

  15. import java.util.List;

  16. import java.util.Map;


  17. /**

  18. * 后台用户管理

  19. * Created by macro on 2018/4/26.

  20. */

  21. @Controller

  22. @Api(tags = "UmsAdminController", description = "后台用户管理")

  23. @RequestMapping("/admin")

  24. public class UmsAdminController {

  25.    @Autowired

  26.    private UmsAdminService adminService;

  27.    @Value("${jwt.tokenHeader}")

  28.    private String tokenHeader;

  29.    @Value("${jwt.tokenHead}")

  30.    private String tokenHead;


  31.    @ApiOperation(value = "用户注册")

  32.    @RequestMapping(value = "/register", method = RequestMethod.POST)

  33.    @ResponseBody

  34.    public CommonResult<UmsAdmin> register(@RequestBody UmsAdmin umsAdminParam, BindingResult result) {

  35.        UmsAdmin umsAdmin = adminService.register(umsAdminParam);

  36.        if (umsAdmin == null) {

  37.            CommonResult.failed();

  38.       }

  39.        return CommonResult.success(umsAdmin);

  40.    }


  41.    @ApiOperation(value = "登录以后返回token")

  42.    @RequestMapping(value = "/login", method = RequestMethod.POST)

  43.    @ResponseBody

  44.    public CommonResult login(@RequestBody UmsAdminLoginParam umsAdminLoginParam, BindingResult result) {

  45.        String token = adminService.login(umsAdminLoginParam.getUsername(), umsAdminLoginParam.getPassword());

  46.        if (token == null) {

  47.            return CommonResult.validateFailed("用户名或密码错误");

  48.       }

  49.        Map<String, String> tokenMap = new HashMap<>();

  50.        tokenMap.put("token", token);

  51.        tokenMap.put("tokenHead", tokenHead);

  52.        return CommonResult.success(tokenMap);

  53.    }


  54.    @ApiOperation("获取用户所有权限(包括+-权限)")

  55.    @RequestMapping(value = "/permission/{adminId}", method = RequestMethod.GET)

  56.    @ResponseBody

  57.    public CommonResult<List<UmsPermission>> getPermissionList(@PathVariable Long adminId) {

  58.        List<UmsPermission> permissionList = adminService.getPermissionList(adminId);

  59.        return CommonResult.success(permissionList);

  60.    }

  61. }

添加UmsAdminService接口

  1. package com.macro.mall.tiny.service;


  2. import com.macro.mall.tiny.mbg.model.UmsAdmin;

  3. import com.macro.mall.tiny.mbg.model.UmsPermission;


  4. import java.util.List;


  5. /**

  6. * 后台管理员Service

  7. * Created by macro on 2018/4/26.

  8. */

  9. public interface UmsAdminService {

  10.    /**

  11.     * 根据用户名获取后台管理员

  12.     */

  13.    UmsAdmin getAdminByUsername(String username);


  14.    /**

  15.     * 注册功能

  16.     */

  17.    UmsAdmin register(UmsAdmin umsAdminParam);


  18.    /**

  19.     * 登录功能

  20.     * @param username 用户名

  21.     * @param password 密码

  22.     * @return 生成的JWT的token

  23.     */

  24.    String login(String username, String password);


  25.    /**

  26.     * 获取用户所有权限(包括角色权限和+-权限)

  27.     */

  28.    List<UmsPermission> getPermissionList(Long adminId);

  29. }

添加UmsAdminServiceImpl类

  1. package com.macro.mall.tiny.service.impl;


  2. import com.macro.mall.tiny.common.utils.JwtTokenUtil;

  3. import com.macro.mall.tiny.dao.UmsAdminRoleRelationDao;

  4. import com.macro.mall.tiny.dto.UmsAdminLoginParam;

  5. import com.macro.mall.tiny.mbg.mapper.UmsAdminMapper;

  6. import com.macro.mall.tiny.mbg.model.UmsAdmin;

  7. import com.macro.mall.tiny.mbg.model.UmsAdminExample;

  8. import com.macro.mall.tiny.mbg.model.UmsPermission;

  9. import com.macro.mall.tiny.service.UmsAdminService;

  10. import org.slf4j.Logger;

  11. import org.slf4j.LoggerFactory;

  12. import org.springframework.beans.BeanUtils;

  13. import org.springframework.beans.factory.annotation.Autowired;

  14. import org.springframework.beans.factory.annotation.Value;

  15. import org.springframework.security.authentication.AuthenticationManager;

  16. import org.springframework.security.authentication.BadCredentialsException;

  17. import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;

  18. import org.springframework.security.core.AuthenticationException;

  19. import org.springframework.security.core.context.SecurityContextHolder;

  20. import org.springframework.security.core.userdetails.UserDetails;

  21. import org.springframework.security.core.userdetails.UserDetailsService;

  22. import org.springframework.security.crypto.password.PasswordEncoder;

  23. import org.springframework.stereotype.Service;


  24. import java.util.Date;

  25. import java.util.List;


  26. /**

  27. * UmsAdminService实现类

  28. * Created by macro on 2018/4/26.

  29. */

  30. @Service

  31. public class UmsAdminServiceImpl implements UmsAdminService {

  32.    private static final Logger LOGGER = LoggerFactory.getLogger(UmsAdminServiceImpl.class);

  33.    @Autowired

  34.    private UserDetailsService userDetailsService;

  35.    @Autowired

  36.    private JwtTokenUtil jwtTokenUtil;

  37.    @Autowired

  38.    private PasswordEncoder passwordEncoder;

  39.    @Value("${jwt.tokenHead}")

  40.    private String tokenHead;

  41.    @Autowired

  42.    private UmsAdminMapper adminMapper;

  43.    @Autowired

  44.    private UmsAdminRoleRelationDao adminRoleRelationDao;


  45.    @Override

  46.    public UmsAdmin getAdminByUsername(String username) {

  47.        UmsAdminExample example = new UmsAdminExample();

  48.        example.createCriteria().andUsernameEqualTo(username);

  49.        List<UmsAdmin> adminList = adminMapper.selectByExample(example);

  50.        if (adminList != null && adminList.size() > 0) {

  51.            return adminList.get(0);

  52.       }

  53.        return null;

  54.    }


  55.    @Override

  56.    public UmsAdmin register(UmsAdmin umsAdminParam) {

  57.        UmsAdmin umsAdmin = new UmsAdmin();

  58.        BeanUtils.copyProperties(umsAdminParam, umsAdmin);

  59.        umsAdmin.setCreateTime(new Date());

  60.        umsAdmin.setStatus(1);

  61.        //查询是否有相同用户名的用户

  62.        UmsAdminExample example = new UmsAdminExample();

  63.        example.createCriteria().andUsernameEqualTo(umsAdmin.getUsername());

  64.        List<UmsAdmin> umsAdminList = adminMapper.selectByExample(example);

  65.        if (umsAdminList.size() > 0) {

  66.            return null;

  67.       }

  68.        //将密码进行加密操作

  69.        String encodePassword = passwordEncoder.encode(umsAdmin.getPassword());

  70.        umsAdmin.setPassword(encodePassword);

  71.        adminMapper.insert(umsAdmin);

  72.        return umsAdmin;

  73.    }


  74.    @Override

  75.    public String login(String username, String password) {

  76.        String token = null;

  77.        try {

  78.            UserDetails userDetails = userDetailsService.loadUserByUsername(username);

  79.            if (!passwordEncoder.matches(password, userDetails.getPassword())) {

  80.                throw new BadCredentialsException("密码不正确");

  81.           }

  82.            UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());

  83.            SecurityContextHolder.getContext().setAuthentication(authentication);

  84.            token = jwtTokenUtil.generateToken(userDetails);

  85.       } catch (AuthenticationException e) {

  86.            LOGGER.warn("登录异常:{}", e.getMessage());

  87.       }

  88.        return token;

  89.    }



  90.    @Override

  91.    public List<UmsPermission> getPermissionList(Long adminId) {

  92.        return adminRoleRelationDao.getPermissionList(adminId);

  93.    }

  94. }

修改Swagger的配置

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

  1. package com.macro.mall.tiny.config;


  2. import org.springframework.context.annotation.Bean;

  3. import org.springframework.context.annotation.Configuration;

  4. import springfox.documentation.builders.ApiInfoBuilder;

  5. import springfox.documentation.builders.PathSelectors;

  6. import springfox.documentation.builders.RequestHandlerSelectors;

  7. import springfox.documentation.service.ApiInfo;

  8. import springfox.documentation.service.ApiKey;

  9. import springfox.documentation.service.AuthorizationScope;

  10. import springfox.documentation.service.SecurityReference;

  11. import springfox.documentation.spi.DocumentationType;

  12. import springfox.documentation.spi.service.contexts.SecurityContext;

  13. import springfox.documentation.spring.web.plugins.Docket;

  14. import springfox.documentation.swagger2.annotations.EnableSwagger2;


  15. import java.util.ArrayList;

  16. import java.util.List;


  17. /**

  18. * Swagger2API文档的配置

  19. */

  20. @Configuration

  21. @EnableSwagger2

  22. public class Swagger2Config {

  23.    @Bean

  24.    public Docket createRestApi(){

  25.        return new Docket(DocumentationType.SWAGGER_2)

  26.                .apiInfo(apiInfo())

  27.                .select()

  28.                //为当前包下controller生成API文档

  29.                .apis(RequestHandlerSelectors.basePackage("com.macro.mall.tiny.controller"))

  30.                .paths(PathSelectors.any())

  31.                .build()

  32.                //添加登录认证

  33.                .securitySchemes(securitySchemes())

  34.                .securityContexts(securityContexts());

  35.    }


  36.    private ApiInfo apiInfo() {

  37.        return new ApiInfoBuilder()

  38.                .title("SwaggerUI演示")

  39.                .description("mall-tiny")

  40.                .contact("macro")

  41.                .version("1.0")

  42.                .build();

  43.    }


  44.    private List<ApiKey> securitySchemes() {

  45.        //设置请求头信息

  46.        List<ApiKey> result = new ArrayList<>();

  47.        ApiKey apiKey = new ApiKey("Authorization", "Authorization", "header");

  48.        result.add(apiKey);

  49.        return result;

  50.    }


  51.    private List<SecurityContext> securityContexts() {

  52.        //设置需要登录认证的路径

  53.        List<SecurityContext> result = new ArrayList<>();

  54.        result.add(getContextByPath("/brand/.*"));

  55.        return result;

  56.    }


  57.    private SecurityContext getContextByPath(String pathRegex){

  58.        return SecurityContext.builder()

  59.                .securityReferences(defaultAuth())

  60.                .forPaths(PathSelectors.regex(pathRegex))

  61.                .build();

  62.    }


  63.    private List<SecurityReference> defaultAuth() {

  64.        List<SecurityReference> result = new ArrayList<>();

  65.        AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");

  66.        AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];

  67.        authorizationScopes[0] = authorizationScope;

  68.        result.add(new SecurityReference("Authorization", authorizationScopes));

  69.        return result;

  70.    }

  71. }

给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。


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: