Spring Security的入门案例!!!

      一、导入依赖

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

二、创建启动类:

/*
 * Copyright (c) 2020, 2024,  All rights reserved.
 *
 */
package com.by;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;

/**
 * <p>Project: ican_parent - SpringSecurityApplication</p>
 * <p>Powered by scl On 2024-01-29 10:44:12</p>
 * <p>描述:<p>
 *
 * @author 孙臣龙 [1846080280@qq.com]
 * @version 1.0
 * @since 17
 */
@SpringBootApplication
//Map<"springSecurityFilterChain",FilterChainProxy> -----> FilterChainProxy ----->doFilterInternal()方法
@EnableWebSecurity //启动security
public class SpringSecurityApplication {
    public static void main(String[] args) {
        ConfigurableApplicationContext applicationContext = SpringApplication.run(SpringSecurityApplication.class, args);
        Object bean = applicationContext.getBean("springSecurityFilterChain");
        System.out.println("-----------------:"+bean.getClass());
    }
}

三、编写配置类

/*
 * Copyright (c) 2020, 2024,  All rights reserved.
 *
 */
package com.by.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;

/**
 * <p>Project: ican_parent - SecurityConfig</p>
 * <p>Powered by scl On 2024-01-29 11:36:09</p>
 * <p>描述:<p>
 *
 * @author 孙臣龙 [1846080280@qq.com]
 * @version 1.0
 * @since 17
 */
@Component
@EnableGlobalMethodSecurity(prePostEnabled = true) //开启权限注解支持
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private UserDetailsService userDetailsService;


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

    /**
     * 配置要放开的页面和配置静态资源
     *
     * @param web
     * @throws Exception
     */
    @Override
    public void configure(WebSecurity web) throws Exception {
        //web.ignoring().antMatchers("/pages/a.html");
        //web.ignoring().antMatchers("/pages/**");
        web.ignoring().antMatchers("/login.html");
    }


    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //super.configure(http);
        //关闭跨站请求
        http.csrf().disable();

        //认证
        http.formLogin()
                .loginPage("/login.html") //登录页面
                .loginProcessingUrl("/login") //表单的请求路径
                .usernameParameter("username")
                .passwordParameter("password")
                .defaultSuccessUrl("/pages/index.html", true);//登录成功后跳转的页面

        //授权
        http.authorizeRequests()
                //.antMatchers("/pages/a.html").hasAuthority("aaa")
                //.antMatchers("/pages/b.html").hasAuthority("bbb")
                //.antMatchers("/pages/c.html").hasRole("CCC") //角色标识符不能用ROLE_开头
                .anyRequest().authenticated();//登录成后,放开权限能够访问其它页面

        //退出登录
        http.logout().logoutUrl("/logout")
                .logoutSuccessUrl("/login.html")
                .invalidateHttpSession(true);
    }

    /**
     * 加密方法,使用直接注入
     *
     * @return
     */
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

四、UserServiceImpl

/*
 * Copyright (c) 2020, 2024,  All rights reserved.
 *
 */
package com.by.service;

import com.by.pojo.UserInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>Project: ican_parent - UserServiceImpl</p>
 * <p>Powered by scl On 2024-01-29 16:37:34</p>
 * <p>描述:<p>
 *
 * @author 孙臣龙 [1846080280@qq.com]
 * @version 1.0
 * @since 17
 */
@Component
public class UserServiceImpl implements UserDetailsService {

    @Autowired
    private PasswordEncoder passwordEncoder;

    private Map<String, UserInfo> mysql = new HashMap<>();

    public void initMysql() {
        mysql.put("admin", new UserInfo("admin", passwordEncoder.encode("111")));
        mysql.put("test", new UserInfo("test", passwordEncoder.encode("111")));
    }


    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        //初始化数据(类似与数据库)
        initMysql();
        //根据前端传过来的参数去数据库中查询
        UserInfo userInfo = mysql.get(username);
        if (userInfo == null) {
            return null;
        }
        String password = userInfo.getPassword();//密码为明文
        //模拟从数据库查询权限
        List<GrantedAuthority> list = new ArrayList<>();
        //通过用户名配置权限
        if (username.equals("admin")) {
            list.add(new SimpleGrantedAuthority("aaa"));
            list.add(new SimpleGrantedAuthority("bbb"));
        } else {
            list.add(new SimpleGrantedAuthority("ROLE_CCC"));
        }

        //为什么不对比密码?程序员只需提供数据,对比密码归security管
        return new User(username, password, list);
    }

}

五、使用注解配置权限

/*
 * Copyright (c) 2020, 2024,  All rights reserved.
 *
 */
package com.by.controller;

import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Collection;

/**
 * <p>Project: ican_parent - HelloController</p>
 * <p>Powered by scl On 2024-01-29 19:50:41</p>
 * <p>描述:<p>
 *
 * @author 孙臣龙 [1846080280@qq.com]
 * @version 1.0
 * @since 17
 */
@RestController
public class HelloController {

    @RequestMapping("/aaa")
    @PreAuthorize("hasAuthority('aaa')")
    public String aaa() {
        return "aaa";
    }

    @RequestMapping("/bbb")
    @PreAuthorize("hasAuthority('bbb')")
    public String bbb() {
        return "bbb";
    }

    @RequestMapping("/ccc")
    @PreAuthorize("hasRole('CCC')")
    public String ccc() {
        return "ccc";
    }

    @RequestMapping("/ddd")
    @PreAuthorize("isAuthenticated()")
    public String ddd() {
        return "ddd";
    }

    /**
     * 获取用户名
     * @param authentication
     * @return
     */
    @GetMapping("/user")
    public String getCurrentUser(Authentication authentication) {
        UserDetails userDetails = (UserDetails) authentication.getPrincipal();
        String username = userDetails.getUsername();
        Collection<? extends GrantedAuthority> authorities = userDetails.getAuthorities();
        // 这里可以根据需要获取更多的用户信息
        return "用户名:" + username + ";角色:" + authorities;
    }


}

六、实体类

package com.by.pojo;

public class UserInfo {
    String username;
    String password;

    public UserInfo(String username,String password){
        this.username = username;
        this.password = password;
    }

    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;
    }

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

七、html页面

a.html、b.html、c.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>a 页面,你瞅啥!!!!</h1>
</body>
</html>

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
就这就这就这!!!!<a href="/logout">退出登录</a><br>
<a href="/user">获取用户名</a>
</body>
</html>

login.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登录页面</title>
</head>
<body>
<h3>自定义登录页面</h3>
<form action="/login" method="post">
    username:<input type="text" name="username"><br>
    password:<input type="password" name="password"><br>
    <input type="submit" value="登录">
</form>
</body>
</html>

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值