springboot简单实现单点登录的示例代码

Spring Boot是一个非常流行的Java Web框架,它提供了很多便捷的功能和工具,可以帮助我们快速构建Web应用程序。其中,单点登录(Single Sign-On,简称SSO)是一个非常重要的功能,可以让用户在多个应用程序之间无需重复登录。以下是Spring Boot简单实现单点登录的示例代码的完整攻略:

  1. 使用Spring Security实现单点登录

Spring Security是Spring Boot中的一个重要组件,它提供了很多安全功能和工具,可以帮助我们实现单点登录。以下是一个示例:

  • 创建一个Spring Boot项目,并添加Spring Security依赖。
  • 创建一个名为SecurityConfig的配置类,并使用@EnableWebSecurity注解来启用Web安全功能。我们使用HttpSecurity对象来配置安全规则,并使用formLogin()方法来启用表单登录功能。
  • 创建一个名为UserController的控制器类,并使用@PreAuthorize注解来限制访问控制器的权限。我们使用@PreAuthorize注解来指定只有具有ROLE_USER角色的用户才能访问控制器。
  • 在application.properties文件中配置Spring Security的用户名和密码。

以下是示例代码:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/user/**").hasRole("USER")
                .anyRequest().authenticated()
                .and()
                .formLogin();
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .withUser("user").password("{noop}password").roles("USER");
    }
}

@RestController
public class UserController {
    @GetMapping("/user")
    @PreAuthorize("hasRole('USER')")
    public String getUser() {
        return "Hello, user!";
    }
}

在上面的示例中,我们使用Spring Security来实现单点登录功能。我们创建了一个名为SecurityConfig的配置类,并使用@EnableWebSecurity注解来启用Web安全功能。我们使用HttpSecurity对象来配置安全规则,并使用formLogin()方法来启用表单登录功能。我们创建了一个名为UserController的控制器类,并使用@PreAuthorize注解来限制访问控制器的权限。我们在application.properties文件中配置了Spring Security的用户名和密码。

  1. 使用JWT实现单点登录

JWT(JSON Web Token)是一种轻量级的身份验证和授权机制,可以帮助我们实现单点登录。以下是一个示例:

  • 创建一个Spring Boot项目,并添加Spring Security和JWT依赖。
  • 创建一个名为JwtTokenUtil的工具类,用于生成和验证JWT令牌。
  • 创建一个名为JwtUserDetailsService的用户服务类,用于从数据库中获取用户信息。
  • 创建一个名为JwtAuthenticationEntryPoint的认证入口类,用于处理认证异常。
  • 创建一个名为JwtAuthenticationTokenFilter的认证过滤器类,用于验证JWT令牌。
  • 创建一个名为JwtAuthorizationTokenFilter的授权过滤器类,用于授权用户访问资源。
  • 创建一个名为UserController的控制器类,并使用@PreAuthorize注解来限制访问控制器的权限。

以下是示例代码:

@Component
public class JwtTokenUtil {
    private static final String SECRET = "mySecret";
    private static final long EXPIRATION_TIME = 864_000_000; // 10 days

    public String generateToken(UserDetails userDetails) {
        Map<String, Object> claims = new HashMap<>();
        return Jwts.builder()
                .setClaims(claims)
                .setSubject(userDetails.getUsername())
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME))
                .signWith(SignatureAlgorithm.HS512, SECRET)
                .compact();
    }

    public String getUsernameFromToken(String token) {
        return Jwts.parser().setSigningKey(SECRET).parseClaimsJws(token).getBody().getSubject();
    }

    public boolean validateToken(String token, UserDetails userDetails) {
        String username = getUsernameFromToken(token);
        return username.equals(userDetails.getUsername()) && !isTokenExpired(token);
    }

    private boolean isTokenExpired(String token) {
        Date expiration = Jwts.parser().setSigningKey(SECRET).parseClaimsJws(token).getBody().getExpiration();
        return expiration.before(new Date());
    }
}

@Service
public class JwtUserDetailsService implements UserDetailsService {
    @Autowired
    private UserRepository userRepository;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userRepository.findByUsername(username);
        if (user == null) {
            throw new UsernameNotFoundException("User not found with username: " + username);
        }
        return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(),
                new ArrayList<>());
    }
}

@Component
public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint {
    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response,
                         AuthenticationException authException) throws IOException {
        response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");
    }
}

public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
    @Autowired
    private JwtUserDetailsService userDetailsService;

    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
            throws ServletException, IOException {
        final String requestTokenHeader = request.getHeader("Authorization");

        String username = null;
        String jwtToken = null;

        if (requestTokenHeader != null && requestTokenHeader.startsWith("Bearer ")) {
            jwtToken = requestTokenHeader.substring(7);
            try {
                username = jwtTokenUtil.getUsernameFromToken(jwtToken);
            } catch (IllegalArgumentException e) {
                logger.error("Unable to get JWT Token");
            } catch (ExpiredJwtException e) {
                logger.error("JWT Token has expired");
            }
        } else {
            logger.warn("JWT Token does not begin with Bearer String");
        }

        if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
            UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);

            if (jwtTokenUtil.validateToken(jwtToken, userDetails)) {
                UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(
                        userDetails, null, userDetails.getAuthorities());
                usernamePasswordAuthenticationToken
                        .setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
            }
        }
        chain.doFilter(request, response);
    }
}

public class JwtAuthorizationTokenFilter extends OncePerRequestFilter {
    @Autowired
    private JwtUserDetailsService userDetailsService;

    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
            throws ServletException, IOException {
        final String requestTokenHeader = request.getHeader("Authorization");

        String username = null;
        String jwtToken = null;

        if (requestTokenHeader != null && requestTokenHeader.startsWith("Bearer ")) {
            jwtToken = requestTokenHeader.substring(7);
            try {
                username = jwtTokenUtil.getUsernameFromToken(jwtToken);
            } catch (IllegalArgumentException e) {
                logger.error("Unable to get JWT Token");
            } catch (ExpiredJwtException e) {
                logger.error("JWT Token has expired");
            }
        } else {
            logger.warn("JWT Token does not begin with Bearer String");
        }

        if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
            UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);

            if (jwtTokenUtil.validateToken(jwtToken, userDetails)) {
                UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(
                        userDetails, null, userDetails.getAuthorities());
                usernamePasswordAuthenticationToken
                        .setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
            }
        }
        chain.doFilter(request, response);
    }
}

@RestController
public class UserController {
    @GetMapping("/user")
    @PreAuthorize("hasRole('USER')")
    public String getUser() {
        return "Hello, user!";
    }
}

在上面的示例中,我们使用JWT来实现单点登录功能。我们创建了一个名为JwtTokenUtil的工具类,用于生成和验证JWT令牌。我们创建了一个名为JwtUserDetailsService的用户服务类,用于从数据库中获取用户信息。我们创建了一个名为JwtAuthenticationEntryPoint的认证入口类,用于处理认证异常。我们创建了一个名为JwtAuthenticationTokenFilter的认证过滤器类,用于验证JWT令牌。我们创建了一个名为JwtAuthorizationTokenFilter的授权过滤器类,用于授权用户访问资源。我们创建了一个名为UserController的控制器类,并使用@PreAuthorize注解来限制访问控制器的权限。

以上是Spring Boot简单实现单点登录的示例代码的完整攻略,其中包括使用Spring Security实现单点登录和使用JWT实现单点登录的示例。根据应用程序的需求和开发人员的经验,可以选择最适合的方法来实现单点登录功能。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:springboot简单实现单点登录的示例代码 - Python技术站

(0)
上一篇 2023年5月15日
下一篇 2023年5月15日

相关文章

  • Java异常学习之自定义异常详解

    Java异常学习之自定义异常详解 自定义异常是什么? 在Java的异常体系中,自定义异常指的是用户自己定义的异常类,继承自Throwable或其子类。自定义异常一般用来处理应用程序特别的异常,例如业务逻辑中的特定条件。 如何定义自定义异常? 定义自定义异常需要遵循以下步骤: 创建一个继承自Exception或其子类的Java类; 添加至少一个构造函数,以便在…

    Java 2023年5月27日
    00
  • MyBatis集成Spring流程详解

    MyBatis集成Spring流程详解 本文将详细介绍如何将MyBatis与Spring整合,以提高Web应用程序的性能和可维护性。 前置条件 在开始本文之前,确保您已经安装了以下环境: Java JDK 1.8或更高版本 Apache Maven 3.6或更高版本 Eclipse IDE或IntelliJ IDEA IDE(任意一个都可以) 此外,您还需要…

    Java 2023年5月19日
    00
  • springboot下配置多数据源的方法

    下面为您介绍在Spring Boot中配置多数据源的方法。 1. 添加依赖 在 pom.xml 文件中添加以下依赖: <!– 数据源驱动依赖 –> <dependency> <groupId>com.zaxxer</groupId> <artifactId>HikariCP</artifa…

    Java 2023年5月20日
    00
  • JS 对java返回的json格式的数据处理方法

    当我们在使用 JavaScript 时,需要对从后端返回的 JSON 格式的数据进行处理。下面是处理 JSON 数据的几种方法和示例说明: 1. 使用 XMLHttpRequest 对象发送 Ajax 请求 使用 XMLHttpRequest,可以向后端发送 XMLHttpRequest 请求获取数据。若要获取 JSON 格式数据,可以使用 XMLHttpR…

    Java 2023年5月26日
    00
  • Java上传文件错误java.lang.NoSuchMethodException的解决办法

    Java上传文件时,可能会出现java.lang.NoSuchMethodException错误,这通常是由于使用了错误的MultipartResolver解析器所致。下面是解决此问题的完整攻略: 1. 确认Spring版本 首先,确认你的Spring版本是否能够支持MultipartResolver解析器。MultipartResolver解析器的支持是从…

    Java 2023年5月25日
    00
  • Spring AOP定义Before增加实战案例详解

    在Spring应用程序中,我们可以使用AOP(面向切面编程)来实现横切关注点的模块化。在本文中,我们将详细介绍如何使用Spring AOP定义Before增强,并提供两个示例说明。 1. Before增强 Before增强是AOP中的一种通知类型,它在目标方法执行之前执行。我们可以使用@Before注解将一个方法标记为Before增强。下面是一个示例代码: …

    Java 2023年5月18日
    00
  • Spring Data JPA 注解Entity关联关系使用详解

    Spring Data JPA是在JPA规范基础上进行了扩展的一种Persistence Framework。在Spring Data JPA中,我们需要使用注解来描述实体类之间的关系。下面,我们将详细讲解“Spring Data JPA 注解Entity关联关系使用详解”的完整攻略。 一、@OneToOne 注解 @OneToOne注解表示一对一关系,常见…

    Java 2023年5月20日
    00
  • jQuery实现在列表的首行添加数据

    下面是详细的jQuery实现在列表的首行添加数据的完整攻略。 过程概述 实现在列表的首行添加数据,可以通过以下步骤完成: 使用jQuery选择器选中列表的第一个元素; 创建需要添加的数据的HTML代码; 使用jQuery的插入方法在第一个元素前插入新增数据。 代码实现 示例 1 在列表首行插入一条文本数据: // 获取列表的第一个元素 var $firstI…

    Java 2023年6月16日
    00
合作推广
合作推广
分享本页
返回顶部