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

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

下面来说说关于单点登录中目前比较流行的一种使用方式,就是springsecurity+jwt实现无状态下用户登录;

JWT

在之前的篇章中大致提到过,使用jwt在分布式项目中进行用户信息的认证很方便,各个模块只需要知道配置的秘钥,就可以解密token中用户的基本信息,完成认证,很方便,关于使用jwt的基本内容可以查阅相关资料,或者参考我之前的一篇;

整理一下思路

1、搭建springboot工程
2、导入springSecurity跟jwt的依赖
3、用户的实体类,dao层,service层(真正开发时再写,这里就直接调用dao层操作数据库)
4、实现UserDetailsService接口
5、实现UserDetails接口
6、验证用户登录信息的拦截器
7、验证用户权限的拦截器
8、springSecurity配置
9、认证的Controller以及测试的controller

项目结构

pom文件

<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-security</artifactId>
		</dependency>

		<!-- https://mvnrepository.com/artifact/org.springframework.security.oauth/spring-security-oauth2 -->
		<dependency>
			<groupId>org.springframework.security.oauth</groupId>
			<artifactId>spring-security-oauth2</artifactId>
			<version>2.3.5.RELEASE</version>
		</dependency>

		<!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-jwt -->
		<dependency>
			<groupId>org.springframework.security</groupId>
			<artifactId>spring-security-jwt</artifactId>
			<version>1.0.10.RELEASE</version>
		</dependency>

		<!-- https://mvnrepository.com/artifact/org.springframework.security.oauth.boot/spring-security-oauth2-autoconfigure -->
		<dependency>
			<groupId>org.springframework.security.oauth.boot</groupId>
			<artifactId>spring-security-oauth2-autoconfigure</artifactId>
			<version>2.1.4.RELEASE</version>
		</dependency>

		<dependency>
			<groupId>io.jsonwebtoken</groupId>
			<artifactId>jjwt</artifactId>
			<version>0.9.1</version>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jpa</artifactId>
		</dependency>

		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
		</dependency>

		<!-- mybatis依赖 -->
		<dependency>
			<groupId>org.mybatis.spring.boot</groupId>
			<artifactId>mybatis-spring-boot-starter</artifactId>
			<version>1.3.0</version>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-jdbc</artifactId>
		</dependency>

		<!-- redis依赖 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-redis</artifactId>
		</dependency>

	</dependencies>

application.properties

server.port=8091

#数据库连接
spring.datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=true
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=root

#mybatis配置
mybatis.type-aliases-package=com.congge.entity
mybatis.mapper-locations=classpath:mybatis/*.xml

#redis配置
spring.session.store-type=redis
spring.redis.database=0
spring,redis.host=127.0.0.1
spring.redis.port=6379
spring.redis.pool.min-idle=10000
spring.redis.timeout=30000

为模拟用户登录,这里提前创建了一个测试使用的表,user

实体类User

public class User {

  private Integer id;

  private String username;

  private String password;

  private String role;

  public Integer getId() {
    return id;
  }

  public void setId(Integer id) {
    this.id = id;
  }

  public String getUsername() {
    return username;
  }

  public void setUsername(String username) {
    this.username = username;
  }

  public String getPassword() {
    return password;
  }

  public void setPassword(String password) {
    this.password = password;
  }

  public String getRole() {
    return role;
  }

  public void setRole(String role) {
    this.role = role;
  }

  @Override
  public String toString() {
    return "User{" +
        "id=" + id +
        ", username='" + username + '\'' +
        ", password='" + password + '\'' +
        ", role='" + role + '\'' +
        '}';
  }
}

Jwt工具类,用于管理token相关的操作,可以单测使用

public class TestJwtUtils {

	public static final String TOKEN_HEADER = "Authorization";
  public static final String TOKEN_PREFIX = "Bearer ";

	public static final String SUBJECT = "congge";

	public static final long EXPIRITION = 1000 * 24 * 60 * 60 * 7;

	public static final String APPSECRET_KEY = "congge_secret";

  private static final String ROLE_CLAIMS = "rol";

	public static String generateJsonWebToken(Users user) {

		if (user.getId() == null || user.getUserName() == null || user.getFaceImage() == null) {
			return null;
		}

		Map<String,Object> map = new HashMap<>();
		map.put(ROLE_CLAIMS, "rol");

		String token = Jwts
				.builder()
				.setSubject(SUBJECT)
				.setClaims(map)
				.claim("id", user.getId())
				.claim("name", user.getUserName())
				.claim("img", user.getFaceImage())
				.setIssuedAt(new Date())
				.setExpiration(new Date(System.currentTimeMillis() + EXPIRITION))
				.signWith(SignatureAlgorithm.HS256, APPSECRET_KEY).compact();
		return token;
	}

	/**
	 * 生成token
	 * @param username
	 * @param role
	 * @return
	 */
	public static String createToken(String username,String role) {

		Map<String,Object> map = new HashMap<>();
		map.put(ROLE_CLAIMS, role);

		String token = Jwts
				.builder()
				.setSubject(username)
				.setClaims(map)
				.claim("username",username)
				.setIssuedAt(new Date())
				.setExpiration(new Date(System.currentTimeMillis() + EXPIRITION))
				.signWith(SignatureAlgorithm.HS256, APPSECRET_KEY).compact();
		return token;
	}

	public static Claims checkJWT(String token) {
		try {
			final Claims claims = Jwts.parser().setSigningKey(APPSECRET_KEY).parseClaimsJws(token).getBody();
			return claims;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 获取用户名
	 * @param token
	 * @return
	 */
	public static String getUsername(String token){
  	Claims claims = Jwts.parser().setSigningKey(APPSECRET_KEY).parseClaimsJws(token).getBody();
  	return claims.get("username").toString();
  }

	/**
	 * 获取用户角色
	 * @param token
	 * @return
	 */
  public static String getUserRole(String token){
  	Claims claims = Jwts.parser().setSigningKey(APPSECRET_KEY).parseClaimsJws(token).getBody();
  	return claims.get("rol").toString();
  }

  /**
   * 是否过期
   * @param token
   * @return
   */
  public static boolean isExpiration(String token){
  	Claims claims = Jwts.parser().setSigningKey(APPSECRET_KEY).parseClaimsJws(token).getBody();
  	return claims.getExpiration().before(new Date());
  }

	public static void main(String[] args) {
		String name = "acong";
		String role = "rol";
		String token = createToken(name,role);
		System.out.println(token);

		Claims claims = checkJWT(token);
		System.out.println(claims.get("username"));

		System.out.println(getUsername(token));
		System.out.println(getUserRole(token));
		System.out.println(isExpiration(token));

	}

	/**
	 * eyJhbGciOiJIUzI1NiJ9.
	 * eyJzdWIiOiJjb25nZ2UiLCJpZCI6IjExMDExIiwibmFtZSI6Im51b3dlaXNpa2kiLCJpbWciOiJ3d3cudW9rby5jb20vMS5wbmciLCJpYXQiOjE1NTQ5OTI1NzksImV4cCI6MTU1NTU5NzM3OX0.
	 * 6DJ9En-UBcTiMRldZeevJq3e1NxJgOWryUyim4_-tEE
	 *
	 * @param args
	 */

	/*public static void main(String[] args) {

		Users user = new Users();
		user.setId("11011");
		user.setUserName("nuoweisiki");
		user.setFaceImage("www.uoko.com/1.png");
		String token = generateJsonWebToken(user);

		System.out.println(token);

		Claims claims = checkJWT(token);
		if (claims != null) {
			String id = claims.get("id").toString();
			String name = claims.get("name").toString();
			String img = claims.get("img").toString();

			String rol = claims.get("rol").toString();

			System.out.println("id:" + id);
			System.out.println("name:" + name);
			System.out.println("img:" + img);

			System.out.println("rol:" + rol);

		}

	}*/

}

操作数据库的类

,这里主要是提供用户注册的一个save用户的方法,

@Service
public class UserService {

	@Autowired
	private UserDao userDao;

	public void save(User user) {
		user.setId(1);
		userDao.save(user);
	}

}

JwtUser

该类封装登录用户相关信息,例如用户名,密码,权限集合等,需要实现UserDetails 接口,

public class JwtUser implements UserDetails {

  private Integer id;
  private String username;
  private String password;
  private Collection<? extends GrantedAuthority> authorities;

  public JwtUser() {
  }

  // 写一个能直接使用user创建jwtUser的构造器
  public JwtUser(User user) {
    id = user.getId();
    username = user.getUsername();
    password = user.getPassword();
    authorities = Collections.singleton(new SimpleGrantedAuthority(user.getRole()));
  }

  public Collection<? extends GrantedAuthority> getAuthorities() {
    return authorities;
  }

  public String getPassword() {
    return password;
  }

  public String getUsername() {
    return username;
  }

  public boolean isAccountNonExpired() {
    return true;
  }

  public boolean isAccountNonLocked() {
    return true;
  }

  public boolean isCredentialsNonExpired() {
    return true;
  }

  public boolean isEnabled() {
    return true;
  }

  @Override
  public String toString() {
    return "JwtUser{" +
        "id=" + id +
        ", username='" + username + '\'' +
        ", password='" + password + '\'' +
        ", authorities=" + authorities +
        '}';
  }

}

配置拦截器

JWTAuthenticationFilter

JWTAuthenticationFilter继承于UsernamePasswordAuthenticationFilter
该拦截器用于获取用户登录的信息,只需创建一个token并调用authenticationManager.authenticate()让spring-security去进行验证就可以了,不用自己查数据库再对比密码了,这一步交给spring去操作。 这个操作有点像是shiro的subject.login(new UsernamePasswordToken()),验证的事情交给框架。

/**
 * 验证用户名密码正确后,生成一个token,并将token返回给客户端
 * 该类继承自UsernamePasswordAuthenticationFilter,重写了其中的2个方法 ,
 * attemptAuthentication:接收并解析用户凭证。
 * successfulAuthentication:用户成功登录后,这个方法会被调用,我们在这个方法里生成token并返回。
 */
public class JWTAuthenticationFilter extends UsernamePasswordAuthenticationFilter {

  private AuthenticationManager authenticationManager;

  public JWTAuthenticationFilter(AuthenticationManager authenticationManager) {
    this.authenticationManager = authenticationManager;
    super.setFilterProcessesUrl("/auth/login");
  }

  @Override
  public Authentication attemptAuthentication(HttpServletRequest request,
                        HttpServletResponse response) throws AuthenticationException {

    // 从输入流中获取到登录的信息
    try {
      LoginUser loginUser = new ObjectMapper().readValue(request.getInputStream(), LoginUser.class);
      return authenticationManager.authenticate(
          new UsernamePasswordAuthenticationToken(loginUser.getUsername(), loginUser.getPassword())
      );
    } catch (IOException e) {
      e.printStackTrace();
      return null;
    }
  }

  // 成功验证后调用的方法
  // 如果验证成功,就生成token并返回
  @Override
  protected void successfulAuthentication(HttpServletRequest request,
                      HttpServletResponse response,
                      FilterChain chain,
                      Authentication authResult) throws IOException, ServletException {

    JwtUser jwtUser = (JwtUser) authResult.getPrincipal();
    System.out.println("jwtUser:" + jwtUser.toString());

    String role = "";
    Collection<? extends GrantedAuthority> authorities = jwtUser.getAuthorities();
    for (GrantedAuthority authority : authorities){
      role = authority.getAuthority();
    }

    String token = TestJwtUtils.createToken(jwtUser.getUsername(), role);
    //String token = JwtTokenUtils.createToken(jwtUser.getUsername(), false);
    // 返回创建成功的token
    // 但是这里创建的token只是单纯的token
    // 按照jwt的规定,最后请求的时候应该是 `Bearer token`
    response.setCharacterEncoding("UTF-8");
    response.setContentType("application/json; charset=utf-8");
    String tokenStr = JwtTokenUtils.TOKEN_PREFIX + token;
    response.setHeader("token",tokenStr);
  }

  @Override
  protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) throws IOException, ServletException {
    response.getWriter().write("authentication failed, reason: " + failed.getMessage());
  }
}

JWTAuthorizationFilter

验证成功当然就是进行鉴权了,每一次需要权限的请求都需要检查该用户是否有该权限去操作该资源,当然这也是框架帮我们做的,那么我们需要做什么呢?很简单,只要告诉spring-security该用户是否已登录,是什么角色,拥有什么权限就可以了。
JWTAuthenticationFilter继承于BasicAuthenticationFilter,至于为什么要继承这个我也不太清楚了,这个我也是网上看到的其中一种实现,实在springSecurity苦手,不过我觉得不继承这个也没事呢(实现以下filter接口或者继承其他filter实现子类也可以吧)只要确保过滤器的顺序,JWTAuthorizationFilter在JWTAuthenticationFilter后面就没问题了。

/**
 * 验证成功当然就是进行鉴权了
 * 登录成功之后走此类进行鉴权操作
 */
public class JWTAuthorizationFilter extends BasicAuthenticationFilter {

  public JWTAuthorizationFilter(AuthenticationManager authenticationManager) {
    super(authenticationManager);
  }

  @Override
  protected void doFilterInternal(HttpServletRequest request,
                  HttpServletResponse response,
                  FilterChain chain) throws IOException, ServletException {

    String tokenHeader = request.getHeader(TestJwtUtils.TOKEN_HEADER);
    // 如果请求头中没有Authorization信息则直接放行了
    if (tokenHeader == null || !tokenHeader.startsWith(TestJwtUtils.TOKEN_PREFIX)) {
      chain.doFilter(request, response);
      return;
    }
    // 如果请求头中有token,则进行解析,并且设置认证信息
    SecurityContextHolder.getContext().setAuthentication(getAuthentication(tokenHeader));
    super.doFilterInternal(request, response, chain);
  }

  // 这里从token中获取用户信息并新建一个token
  private UsernamePasswordAuthenticationToken getAuthentication(String tokenHeader) {
    String token = tokenHeader.replace(TestJwtUtils.TOKEN_PREFIX, "");
    String username = TestJwtUtils.getUsername(token);
    String role = TestJwtUtils.getUserRole(token);
    if (username != null){
      return new UsernamePasswordAuthenticationToken(username, null,
          Collections.singleton(new SimpleGrantedAuthority(role))
      );
    }
    return null;
  }
}

配置SpringSecurity

到这里基本操作都写好啦,现在就需要我们将这些辛苦写好的“组件”组合到一起发挥作用了,那就需要配置了。需要开启一下注解@EnableWebSecurity然后再继承一下WebSecurityConfigurerAdapter就可以啦,

@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

  @Autowired
  @Qualifier("userDetailsServiceImpl")
  private UserDetailsService userDetailsService;

  @Bean
  public BCryptPasswordEncoder bCryptPasswordEncoder(){
    return new BCryptPasswordEncoder();
  }

  @Override
  protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder());
  }

  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http.cors().and().csrf().disable()
        .authorizeRequests()
        // 测试用资源,需要验证了的用户才能访问
        .antMatchers("/tasks/**")
        .authenticated()
        .antMatchers(HttpMethod.DELETE, "/tasks/**")
        .hasRole("ADMIN")
        // 其他都放行了
        .anyRequest().permitAll()
        .and()
        .addFilter(new JWTAuthenticationFilter(authenticationManager()))
        .addFilter(new JWTAuthorizationFilter(authenticationManager()))
        // 不需要session
        .sessionManagement()
        .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
        .and()
        .exceptionHandling()
        .authenticationEntryPoint(new JWTAuthenticationEntryPoint());
  }

  @Bean
  CorsConfigurationSource corsConfigurationSource() {
    final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", new CorsConfiguration().applyPermitDefaultValues());
    return source;
  }
}

AuthController

测试类,模拟用户注册,

@RestController
@RequestMapping("/auth")
public class AuthController {

  @Autowired
  private UserService userService;

  @Autowired
  private BCryptPasswordEncoder bCryptPasswordEncoder;

  @PostMapping("/register")
  public String registerUser(@RequestBody Map<String,String> registerUser){
    User user = new User();
    user.setUsername(registerUser.get("username"));
    user.setPassword(bCryptPasswordEncoder.encode(registerUser.get("password")));
    user.setRole("ROLE_USER");
    userService.save(user);
    return "success";
  }
}

注册是有了,那登录在哪呢?我们看一下UsernamePasswordAuthenticationFilter的源代码

public UsernamePasswordAuthenticationFilter() {
    super(new AntPathRequestMatcher("/login", "POST"));
  }

可以看出来默认是/login,所以登录直接使用这个路径就可以啦~当然也可以自定义
只需要在JWTAuthenticationFilter的构造方法中加入下面那一句话就可以啦

 public JWTAuthenticationFilter(AuthenticationManager authenticationManager) {
    this.authenticationManager = authenticationManager;
    super.setFilterProcessesUrl("/auth/login");
  }

所以现在认证的路径统一了一下也是挺好的~看起来相当舒服了
注册:/auth/register
登录:/auth/login

TaskController

提供一个外部访问的API资源接口,即用户要访问该类下面的接口必须要先通过认证,后面的测试中也可以看出来,直接贴代码,

@RequestMapping("/tasks")
public class TaskController {

  @GetMapping("/getTasks")
  @ResponseBody
  public String listTasks(){
    return "任务列表";
  }

  @PostMapping
  @PreAuthorize("hasRole('ADMIN')")
  public String newTasks(){
    return "创建了一个新的任务";
  }
}

下面我们来测试一下,为了模拟效果比较直观点,我们使用postMan进行测试,

1、首先,我们调用注册的方法注册一个用户,

注册成功之后,我们看到数据库已经有了一个用户,

2、使用该用户进行登录,我们希望的是登录成功之后,后台生成一个token并返回给前端,这样后面的接口调用中直接带上这个token即可,

可以看到登录成功,后台反返回了token,下面我们使用这个token请求其他的接口,测试一下getTasks这个接口,注意需要在postMan的请求header里面带上token信息,这里是全部的token,即包含Bearer 的整个字符串,

这时候,成功请求到了接口的数据,大家可以测试一下将过期时间调整的短一点,然后再去请求看看会有什么样的效果,这里就不做演示了。

本篇到这里基本就结束了,关于springsecurity其实内容还是很多的,里面的用法也比较复杂,大家抽空可以做深入的研究,篇幅原因不做过多介绍了。最后感谢观看。

附上源码地址:boot-ssoserver_jb51.rar

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

(0)

相关推荐

  • Spring Boot Security 结合 JWT 实现无状态的分布式API接口

    简介 JSON Web Token(缩写 JWT)是目前最流行的跨域认证解决方案.JSON Web Token 入门教程 这篇文章可以帮你了解JWT的概念.本文重点讲解Spring Boot 结合 jwt ,来实现前后端分离中,接口的安全调用. Spring Security,这是一种基于 Spring AOP 和 Servlet 过滤器的安全框架.它提供全面的安全性解决方案,同时在 Web 请求级和方法调用级处理身份确认和授权. 快速上手 之前的文章已经对 Spring Security 进行

  • SpringBoot Security整合JWT授权RestAPI的实现

    本教程主要详细讲解SpringBoot Security整合JWT授权RestAPI. 基础环境 技术 版本 Java 1.8+ SpringBoot 2.x.x Security 5.x JWT 0.9.0 创建项目 初始化项目 mvn archetype:generate -DgroupId=com.edurt.sli.slisj -DartifactId=spring-learn-integration-security-jwt -DarchetypeArtifactId=maven-ar

  • 详解SpringBoot+SpringSecurity+jwt整合及初体验

    原来一直使用shiro做安全框架,配置起来相当方便,正好有机会接触下SpringSecurity,学习下这个.顺道结合下jwt,把安全信息管理的问题扔给客户端, 准备 首先用的是SpringBoot,省去写各种xml的时间.然后把依赖加入一下 <!--安全--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-secu

  • SpringBoot集成Spring Security用JWT令牌实现登录和鉴权的方法

    最近在做项目的过程中 需要用JWT做登录和鉴权 查了很多资料 都不甚详细 有的是需要在application.yml里进行jwt的配置 但我在导包后并没有相应的配置项 因而并不适用 在踩过很多坑之后 稍微整理了一下 做个笔记 一.概念 1.什么是JWT Json Web Token (JWT)是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准(RFC 7519) 该token被设计为紧凑且安全的 特别适用于分布式站点的单点登录(SSO)场景 随着JWT的出现 使得校验方式更加简单便

  • Spring Boot(四)之使用JWT和Spring Security保护REST API

    通常情况下,把API直接暴露出去是风险很大的,不说别的,直接被机器攻击就喝一壶的.那么一般来说,对API要划分出一定的权限级别,然后做一个用户的鉴权,依据鉴权结果给予用户开放对应的API.目前,比较主流的方案有几种: 用户名和密码鉴权,使用Session保存用户鉴权结果. 使用OAuth进行鉴权(其实OAuth也是一种基于Token的鉴权,只是没有规定Token的生成方式) 自行采用Token进行鉴权 第一种就不介绍了,由于依赖Session来维护状态,也不太适合移动时代,新的项目就不要采用了.

  • SpringBoot集成SpringSecurity和JWT做登陆鉴权的实现

    废话 目前流行的前后端分离让Java程序员可以更加专注的做好后台业务逻辑的功能实现,提供如返回Json格式的数据接口就可以.SpringBoot的易用性和对其他框架的高度集成,用来快速开发一个小型应用是最佳的选择. 一套前后端分离的后台项目,刚开始就要面对的就是登陆和授权的问题.这里提供一套方案供大家参考. 主要看点: 登陆后获取token,根据token来请求资源 根据用户角色来确定对资源的访问权限 统一异常处理 返回标准的Json格式数据 正文 首先是pom文件: <dependencies

  • SpringBoot+Spring Security+JWT实现RESTful Api权限控制的方法

    摘要:用spring-boot开发RESTful API非常的方便,在生产环境中,对发布的API增加授权保护是非常必要的.现在我们来看如何利用JWT技术为API增加授权保护,保证只有获得授权的用户才能够访问API. 一:开发一个简单的API 在IDEA开发工具中新建一个maven工程,添加对应的依赖如下: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-b

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

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

  • 详解使用Spring3 实现用户登录以及权限认证

    使用Spring3 实现用户登录以及权限认证 这里我就简单介绍一下,我在实现的时候处理的一些主要的实现. 1.用户登录 <form action="loginAction.do" method="post"> <div class="header"> <h2 class="logo png"></h2> </div> <ul> <li><

  • springboot+springsecurity如何实现动态url细粒度权限认证

    谨记:Url表只储存受保护的资源,不在表里的资源说明不受保护,任何人都可以访问 1.MyFilterInvocationSecurityMetadataSource 类判断该访问路径是否被保护 @Component //用于设置受保护资源的权限信息的数据源 public class MyFilterInvocationSecurityMetadataSource implements FilterInvocationSecurityMetadataSource { @Bean public An

  • SpringBoot+SpringSecurity+jwt实现验证

    目录 环境 目录结构信息 记录一下使用springSecurity实现jwt的授权方法,这方法可以实现权限的基本认证.当然这个案例还有许多的问题,不过还是先记录一下.其他功能以后在补充. 建议工程创建流程 创建 JwtTokenUtils 创建 jwtAccessDeniedHandler 和 JwtAuthenticationEntryPoint 创建 UserDetailsServiceImpl 创建 JwtAuthenticationFilter 配置 Security信息 启动类的信息

  • 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

  • django使用JWT保存用户登录信息

    在使用前必须弄明白JWT的相关知识,可以看我的另一篇博文:https://www.jb51.net/article/166843.htm 什么是JWT? Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该token被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO)场景.JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也可以增加一些额外的其它业务逻辑

  • Springboot+SpringSecurity实现图片验证码登录的示例

    这个问题,网上找了好多,结果代码都不全,找了好多,要不是就自动注入的类注入不了,编译报错,要不异常捕获不了浪费好多时间,就觉得,框架不熟就不能随便用,全是坑,气死我了,最后改了两天.终于弄好啦; 问题主要是: 返回的验证码不知道在SpringSecurity的什么地方和存在内存里的比较?我用的方法是前置一个过滤器,插入到表单验证之前. 比较之后应该怎么处理,:比较之后要抛出一个继承了AuthenticationException的异常 其次是捕获验证码错误异常的处理? 捕获到的异常交给自定义验证

  • SpringBoot+SpringSecurity实现基于真实数据的授权认证

    (一)概述 Spring Security是一个功能强大且高度可定制的身份验证和访问控制框架,Spring Security主要做两个事情,认证.授权.我之前写过一篇关于SpringSecurity的博客,但是当时只是介绍了基于mock数据的案例,本期就来介绍一下基于真实数据的认证授权实现. (二)前期项目搭建 为了更好的展示SpringSecurity,我们先搭建一个简单的web项目出来.引入thymeleaf依赖 <dependency> <groupId>org.spring

  • laravel利用中间件做防非法登录和权限控制示例

    laravel框架的中间件非常好用,使得我们的防非法和rbac可以简单快速的实现 中间件就是控制路由的访问,进行分类并统一管理 1.首先我们打开artisan输入下面的命令行,创建一个中间件文件 php artisan make:middleware AdminLogin 执行命令后我们会发现Middleware文件夹会多出一个AdminLogin文件 2.然后我们打开kernel.php,将这个中间件加入到路由中间件中 protected $routeMiddleware = [ 'auth'

随机推荐