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中提供了多种实现生产者消费者问题的方法,具体如下: 方法一:使用wait()和notify()方法 这是最基本的一种实现方式。使用wait()方法让生产者线程等待,当消息队列满时…

    Java 2023年5月18日
    00
  • Java实现按键精灵的示例代码

    讲解Java实现按键精灵的示例代码的攻略如下: 环境准备 首先需要安装好Java,并安装相应的开发工具,比如Eclipse、IntelliJ IDEA等。同时需要引入按键精灵的Java API,一般情况下直接将其引入到项目中即可。 示例1:模拟键盘输入 按键精灵主要用于模拟用户键盘输入,因此我们首先要实现键盘输入。 在Java中,可以使用Robot类来模拟键…

    Java 2023年5月19日
    00
  • jsp中为表格添加水平滚动条的实现方法

    以下是实现在JSP页面中为表格添加水平滚动条的完整攻略: 准备工作 首先,我们需要在JSP页面中定义表格。在表格标签中添加样式,以保证表格超出容器时出现水平滚动条。例如,我们可以定义一个class为“scroll-table”的样式,代码如下: <style> .scroll-table { width: 100%; overflow-x: sc…

    Java 2023年6月15日
    00
  • Java零基础教程之Windows下安装、启动Tomcat服务器方法图解(免安装版)

    Java零基础教程之Windows下安装、启动Tomcat服务器方法图解(免安装版) 简介 本文主要介绍在Windows系统下,如何安装、启动Tomcat服务器,并提供免安装版步骤图解。 准备 在开始安装Tomcat服务器之前,需要满足以下条件: 安装Java开发工具包(JDK) 下载Tomcat服务器 安装JDK 在官网Java SE下载页面下载适用于Wi…

    Java 2023年5月20日
    00
  • 浅谈JAVA8给我带了什么——流的概念和收集器

    浅谈JAVA8给我带了什么——流的概念和收集器 流的概念 流指的是Java 8中引入的一种新的数据处理方式,它可以被抽象为一个支持并行处理的元素序列。在流中,数据源本身可以是一个数组、集合、I/O channel、产生元素序列的generator function等。与集合不同的是,流本身并不储存数据,它只是对数据源中数据的一种延迟计算视图,数据源中的元素能…

    Java 2023年5月19日
    00
  • SpringSecurity如何实现配置单个HttpSecurity

    要实现配置单个HttpSecurity,可以通过在配置类中创建多个protected的方法,并使用@Order注解来指定它们的顺序来实现。每个protected方法都会配置一个单独的HttpSecurity对象。 下面是实现的步骤: 创建一个配置类,并添加@EnableWebSecurity注解。 在配置类中创建多个被@Order注解标记的protected…

    Java 2023年5月20日
    00
  • Java实现AES算法的实例代码

    以下是Java实现AES算法的实例代码的完整攻略。 1. 什么是AES算法? AES(Advanced Encryption Standard,高级加密标准)是一种常见的对称加密算法,可用于加密和解密数据。它支持128位、192位和256位密钥长度,并被广泛应用于安全通信和数据保护领域。 2. AES算法的Java实现 Java 提供了一个官方实现的AES算…

    Java 2023年5月19日
    00
  • 浅谈mybatis中SQL语句给boolean类型赋值问题

    谈到MyBatis中SQL语句给boolean类型赋值问题,需要注意以下几点: 在Java中,boolean类型的变量只有两个取值:true和false,在SQL语句中需要对应相应的取值 MyBatis中使用动态SQL语句,使用OGNL来指定参数值 则,对于bool类型的参数,SQL语句中的取值应该为真正对应的字符串。在MyBatis中,常规的做法是使用”1…

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