011SpringBoot--Security(安全)

目录

简介

注意:

准备工作

pom.xml

RouterController

 特别讲解:

一、授权 

SecurityConfig---1.1

SecurityConfig---1.2  

源码  formLogin 

二、身份验证

核心类:Authentication   身份验证

 SecurityConfig---2.1

  SecurityConfig---2.2

 JDBC

 源码 auth.inMemoryAuthentication()

三、注销  http.logout();

源码   http.logout();

实例: 

四、防止网站被攻击

五、权限登录---根据不同的用户显示不同的版块

 Security—thymeleaf整合

1.导入命名空间

2.  上面隐藏

3.下面隐藏

六、记住我功能

七、定制自己的登录页面

 问题一:前后端页面请求url 不一致

 方式一: 修改前后端修改一致

 方式二: loginProcessingUrl

 问题二: 前后端传递参数不一致

SecurityConfig 

 RouterController


简介

Spring Security是针对Spring项目的安全框架,也是SpringBoot底层安全模块默认的技术选型,他可以实现强大的Web安全控制,对于安全控制,我们仅需要引入spring-boot-starter-security模块,进行少量的配置,即可实现强大的安全管理!

记住几个类:

  •  WebSecurityConfigurerAdapter: 自定义Security策略
  • AuthenticationManagerBuilder:自定义认证策略   
  • @EnableWebSecurity:开启WebSecurity模式 
  • 日后看见@Enablexxxx   就是开启某个功能

Spring Security的两个主要目标是“认证”和“授权”(访问控制)。

"认证”(Authentication)

"授权"(Authorization)

这个概念是通用的,而不是只在Spring Security中存在。参考官网:

注意:

      SpringBoot支持Security 版本不超过 2.0.9  

官网:Spring Security Reference

准备工作

pom.xml

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

RouterController

@Controller
public class RouterController {

    @RequestMapping({"/","/index"})
    public String toIndex(){
        return "index";
    }

    @RequestMapping("/toLogin")
    public String toLogin(){
        return "views/login";
    }

    @RequestMapping("/level1/{id}")
    public String toLevel1(@PathVariable("id")Integer id){
        return "views/level1/"+id;
    }

    @RequestMapping("/level2/{id}")
    public String toLevel2(@PathVariable("id")Integer id){
        return "views/level2/"+id;
    }

    @RequestMapping("/level3/{id}")
    public String toLevel3(@PathVariable("id")Integer id){
        return "views/level3/"+id;
    }

}

 特别讲解:

    @RequestMapping("/level1/{id}")
    public String toLevel1(@PathVariable("id")Integer id){
        return "views/level1/"+id;
    }

一、授权 

SecurityConfig---1.1

//AOP : 拦截器!
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {


    //授权   链式编程
    @Override
    protected void configure(HttpSecurity http) throws Exception {

        //首页所有人可以访问,功能页只有对应有权限的人才能访问
        //请求授权的规则
        http.authorizeRequests().antMatchers("/","/index").permitAll()   //首页所有人可以访问
                .antMatchers("/level1/**").hasRole("vip1")               //level1  下得所有页面   需要拥有 hasRole vip1 才可以访问
                .antMatchers("/level2/**").hasRole("vip2")               //level2  下得所有页面   需要拥有 hasRole vip2 才可以访问
                .antMatchers("/level3/**").hasRole("vip3");              //level3  下得所有页面   需要拥有 hasRole vip3 才可以访问
    }
}

SecurityConfig---1.2  

//AOP : 拦截器!
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {


    //授权   链式编程
    @Override
    protected void configure(HttpSecurity http) throws Exception {

        //首页所有人可以访问,功能页只有对应有权限的人才能访问
        //请求授权的规则
        http.authorizeRequests().antMatchers("/","/index").permitAll()   //首页所有人可以访问
                .antMatchers("/level1/**").hasRole("vip1")               //level1  下得所有页面   需要拥有 hasRole vip1 才可以访问
                .antMatchers("/level2/**").hasRole("vip2")               //level2  下得所有页面   需要拥有 hasRole vip2 才可以访问
                .antMatchers("/level3/**").hasRole("vip3");              //level3  下得所有页面   需要拥有 hasRole vip3 才可以访问


        //没有权限 默认跳到登录页面
        http.formLogin();
    }
}

源码  formLogin 

	/**
	 * Specifies to support form based authentication. If
	 * {@link FormLoginConfigurer#loginPage(String)} is not specified a default login page
	 * will be generated.
	 *
	 * <h2>Example Configurations</h2>
	 *
	 * The most basic configuration defaults to automatically generating a login page at
	 * the URL "/login", redirecting to "/login?error" for authentication failure. The
	 * details of the login page can be found on
	 * {@link FormLoginConfigurer#loginPage(String)}
	 *
	 * <pre>
	 * &#064;Configuration
	 * &#064;EnableWebSecurity
	 * public class FormLoginSecurityConfig extends WebSecurityConfigurerAdapter {
	 *
	 * 	&#064;Override
	 * 	protected void configure(HttpSecurity http) throws Exception {
	 * 		http.authorizeRequests().antMatchers(&quot;/**&quot;).hasRole(&quot;USER&quot;).and().formLogin();
	 * 	}
	 *
	 * 	&#064;Override
	 * 	protected void configure(AuthenticationManagerBuilder auth) throws Exception {
	 * 		auth.inMemoryAuthentication().withUser(&quot;user&quot;).password(&quot;password&quot;).roles(&quot;USER&quot;);
	 * 	}
	 * }
	 * </pre>
	 *
	 * The configuration below demonstrates customizing the defaults.
	 *
	 * <pre>
	 * &#064;Configuration
	 * &#064;EnableWebSecurity
	 * public class FormLoginSecurityConfig extends WebSecurityConfigurerAdapter {
	 *
	 * 	&#064;Override
	 * 	protected void configure(HttpSecurity http) throws Exception {
	 * 		http.authorizeRequests().antMatchers(&quot;/**&quot;).hasRole(&quot;USER&quot;).and().formLogin()
	 * 				.usernameParameter(&quot;username&quot;) // default is username
	 * 				.passwordParameter(&quot;password&quot;) // default is password
	 * 				.loginPage(&quot;/authentication/login&quot;) // default is /login with an HTTP get
	 * 				.failureUrl(&quot;/authentication/login?failed&quot;) // default is /login?error
	 * 				.loginProcessingUrl(&quot;/authentication/login/process&quot;); // default is /login
	 * 																		// with an HTTP
	 * 																		// post
	 * 	}
	 *
	 * 	&#064;Override
	 * 	protected void configure(AuthenticationManagerBuilder auth) throws Exception {
	 * 		auth.inMemoryAuthentication().withUser(&quot;user&quot;).password(&quot;password&quot;).roles(&quot;USER&quot;);
	 * 	}
	 * }
	 * </pre>
	 *
	 * @see FormLoginConfigurer#loginPage(String)
	 *
	 * @return the {@link FormLoginConfigurer} for further customizations
	 * @throws Exception
	 */
	public FormLoginConfigurer<HttpSecurity> formLogin() throws Exception {
		return getOrApply(new FormLoginConfigurer<>());
	}

二、身份验证

核心类:Authentication   身份验证

注:

//认证  springboot 2.1.X 可以直接使用
//密码编码  PasswordEncoder
//在spring Security 5.0+ 新增了很多的加密方法~

 底部

 SecurityConfig---2.1

    //认证
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {

         //这些数据正常应该从数据库中读取 jdbcAuthentication()     此时是 内存中读取inMemoryAuthentication
        auth.inMemoryAuthentication()
                .withUser("kuangshen").password("123456").roles("vip2","vip3")
                .and()
                .withUser("root").password("123456").roles("vip1","vip2","vip3")
                .and()
                .withUser("guest").password("123456").roles("vip1","vip3")
}

  SecurityConfig---2.2

    //认证  springboot 2.1.X 可以直接使用
    //密码编码  PasswordEncoder
    //在spring Security 5.0+ 新增了很多的加密方法~
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {

        //这些数据正常应该从数据库中读取 jdbcAuthentication()     此时是 内存中读取inMemoryAuthentication
        auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder()) //密码加密的方式
                .withUser("kuangshen").password(new BCryptPasswordEncoder().encode("123456")).roles("vip2","vip3") //编码
                .and()
                .withUser("root").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2","vip3")
                .and()
                .withUser("guest").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1");

    }
}

 JDBC

 源码 auth.inMemoryAuthentication()

 

三、注销  http.logout();

//AOP : 拦截器!
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {


    //授权   链式编程
    @Override
    protected void configure(HttpSecurity http) throws Exception {

        //首页所有人可以访问,功能页只有对应有权限的人才能访问
        //请求授权的规则
        http.authorizeRequests().antMatchers("/","/index").permitAll()   //首页所有人可以访问
                .antMatchers("/level1/**").hasRole("vip1")               //level1  下得所有页面   需要拥有 hasRole vip1 才可以访问
                .antMatchers("/level2/**").hasRole("vip2")               //level2  下得所有页面   需要拥有 hasRole vip2 才可以访问
                .antMatchers("/level3/**").hasRole("vip3");              //level3  下得所有页面   需要拥有 hasRole vip3 才可以访问


        //没有权限 默认跳到登录页面
        http.formLogin();
            
        //注销,开启了注销功能
        http.logout();
    }
}
http.logout().deleteCookies("remove").invalidateHttpSession(true);//移除所有的Cookie  清空所有的Session 

//注销    登出成功后跳转到 首页
http.logout().logoutSuccessUrl("/");

 

源码   http.logout();

	/**
	 * Provides logout support. This is automatically applied when using
	 * {@link WebSecurityConfigurerAdapter}. The default is that accessing the URL
	 * "/logout" will log the user out by invalidating the HTTP Session, cleaning up any
	 * {@link #rememberMe()} authentication that was configured, clearing the
	 * {@link SecurityContextHolder}, and then redirect to "/login?success".
	 *
	 * <h2>Example Custom Configuration</h2>
	 *
	 * The following customization to log out when the URL "/custom-logout" is invoked.
	 * Log out will remove the cookie named "remove", not invalidate the HttpSession,
	 * clear the SecurityContextHolder, and upon completion redirect to "/logout-success".
	 *
	 * <pre>
	 * &#064;Configuration
	 * &#064;EnableWebSecurity
	 * public class LogoutSecurityConfig extends WebSecurityConfigurerAdapter {
	 *
	 * 	&#064;Override
	 * 	protected void configure(HttpSecurity http) throws Exception {
	 * 		http.authorizeRequests().antMatchers(&quot;/**&quot;).hasRole(&quot;USER&quot;).and().formLogin()
	 * 				.and()
	 * 				// sample logout customization
	 * 				.logout().deleteCookies(&quot;remove&quot;).invalidateHttpSession(false)
	 * 				.logoutUrl(&quot;/custom-logout&quot;).logoutSuccessUrl(&quot;/logout-success&quot;);
	 * 	}
	 *
	 * 	&#064;Override
	 * 	protected void configure(AuthenticationManagerBuilder auth) throws Exception {
	 * 		auth.inMemoryAuthentication().withUser(&quot;user&quot;).password(&quot;password&quot;).roles(&quot;USER&quot;);
	 * 	}
	 * }
	 * </pre>
	 *
	 * @return the {@link LogoutConfigurer} for further customizations
	 * @throws Exception
	 */

实例: 

四、防止网站被攻击

//防止网站攻击工具  get post  
http.csrf().disable(); //关闭csrf 功能   登出失败 可能存在的原因

五、权限登录---根据不同的用户显示不同的版块

 Security—thymeleaf整合

        <!--Security———thymeleaf 整合-->
        <dependency>
            <groupId>org.thymeleaf.extras</groupId>
            <artifactId>thymeleaf-extras-springsecurity4</artifactId>
            <version>3.0.4.RELEASE</version>
        </dependency>

作用: 在 thymeleaf 中可以写一些  Security 的操作

1.导入命名空间

xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4"

2.  上面隐藏

            <!--登录注销-->
            <div class="right menu">

                <!--未登录  显示登录页面   authorize v. 批准,许可;授权 -->
                <div sec:authorize="!isAuthenticated()">  <!--!isAuthenticated()未登录-->
                    <a class="item" th:href="@{/toLogin}">
                        <i class="address card icon"></i> 登录
                    </a>
                </div>

                <!-- 已登录 显示注销和用户名 -->
                <div sec:authorize="isAuthenticated()">
                    <a class="item">
                        用户名:<span sec:authentication="principal.username"></span>
                        权限:<span sec:authentication="principal.authorities"></span>
                        <!--角色:<span sec:authentication="principal.getPassword()"></span>-->
                    </a>
                </div>
                <div sec:authorize="isAuthenticated()">
                    <!--注销-->
                    <a class="item" th:href="@{/logout}">
                        <i class="sign-out icon"></i> 注销
                    </a>
                </div>

            </div>

3.下面隐藏

            <!--根据用户的角色动态实现-->
            <div class="column" sec:authorize="hasRole('vip1')">
                <div class="ui raised segment">
                    <div class="ui">
                        <div class="content">
                            <h5 class="content">Level 1</h5>
                            <hr>
                            <div><a th:href="@{/level1/1}"><i class="bullhorn icon"></i> Level-1-1</a></div>
                            <div><a th:href="@{/level1/2}"><i class="bullhorn icon"></i> Level-1-2</a></div>
                            <div><a th:href="@{/level1/3}"><i class="bullhorn icon"></i> Level-1-3</a></div>
                        </div>
                    </div>
                </div>
            </div>

            <div class="column" sec:authorize="hasRole('vip2')">
                <div class="ui raised segment">
                    <div class="ui">
                        <div class="content">
                            <h5 class="content">Level 2</h5>
                            <hr>
                            <div><a th:href="@{/level2/1}"><i class="bullhorn icon"></i> Level-2-1</a></div>
                            <div><a th:href="@{/level2/2}"><i class="bullhorn icon"></i> Level-2-2</a></div>
                            <div><a th:href="@{/level2/3}"><i class="bullhorn icon"></i> Level-2-3</a></div>
                        </div>
                    </div>
                </div>
            </div>

            <div class="column" sec:authorize="hasRole('vip3')">
                <div class="ui raised segment">
                    <div class="ui">
                        <div class="content">
                            <h5 class="content">Level 3</h5>
                            <hr>
                            <div><a th:href="@{/level3/1}"><i class="bullhorn icon"></i> Level-3-1</a></div>
                            <div><a th:href="@{/level3/2}"><i class="bullhorn icon"></i> Level-3-2</a></div>
                            <div><a th:href="@{/level3/3}"><i class="bullhorn icon"></i> Level-3-3</a></div>
                        </div>
                    </div>
                </div>
            </div>

六、记住我功能

//记住我功能 cookie  默认保存两周
//rememberMeParameter 记住我的参数
http.rememberMe().rememberMeParameter("remember");

七、定制自己的登录页面

//定制自己的登录页面
http.formLogin().loginPage("/toLogin");

 问题一:前后端页面请求url 不一致

 方式一: 修改前后端修改一致

 方式二: loginProcessingUrl

        http.formLogin().loginPage("/toLogin").loginProcessingUrl("/login");

 问题二: 前后端传递参数不一致

        //前后端 传递的参数不一致   默认 username  password
        http.formLogin().loginPage("/toLogin")
                .usernameParameter("user")
                .passwordParameter("pwd").loginProcessingUrl("/login");

 

SecurityConfig 

/**
 *  Security配置文件
 */
//AOP : 拦截器!
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {


    //授权   链式编程
    @Override
    protected void configure(HttpSecurity http) throws Exception {

        //首页所有人可以访问,功能页只有对应有权限的人才能访问
        //请求授权的规则
        http.authorizeRequests().antMatchers("/","/index").permitAll()   //首页所有人可以访问
                .antMatchers("/level1/**").hasRole("vip1")               //level1  下得所有页面   需要拥有 hasRole vip1 才可以访问
                .antMatchers("/level2/**").hasRole("vip2")               //level2  下得所有页面   需要拥有 hasRole vip2 才可以访问
                .antMatchers("/level3/**").hasRole("vip3");              //level3  下得所有页面   需要拥有 hasRole vip3 才可以访问

        //没有权限 默认跳到登录页面
        http.formLogin();

        //定制自己的登录页面
        //  方式一:
//        http.formLogin().loginPage("/toLogin");     网页请求写 toLogin

        //  问题一:  loginProcessingUrl 登录认证的是那个url  网页写 login
        http.formLogin().loginPage("/toLogin").loginProcessingUrl("/login");

        // 问题二: 前后端 传递的参数不一致   默认 username  password
//        http.formLogin().loginPage("/toLogin")
//                .usernameParameter("user")
//                .passwordParameter("pwd").loginProcessingUrl("/login");

        //注销    登出成功后跳转到index.html
        http.logout();

        //注销    登出成功后跳转到 首页
        http.logout().logoutSuccessUrl("/");

        //防止网站攻击工具  get post
        http.csrf().disable(); //关闭csrf 功能  登出失败 可能存在的原因

        //记住我功能 cookie  默认保存两周
        //rememberMeParameter 记住我的参数
        http.rememberMe().rememberMeParameter("remember");

//        //定制首页可以随意访问   另一种方式
//        http.authorizeRequests().antMatchers("/","/index").permitAll();
//
//        //level1页面:vip1 2 3 都可以访问该页面
//        http.authorizeRequests().antMatchers("/level1/**").hasRole("vip1");
//
//        //level2页面:vip2 3可以访问
//        http.authorizeRequests().antMatchers("/level2/**").hasRole("vip2");
//
//        //level3页面:vip3才能访问
//        http.authorizeRequests().antMatchers("/level3/**").hasRole("vip3");


    }

    //认证  springboot 2.1.X 可以直接使用
    //密码编码  PasswordEncoder
    //在spring Security 5.0+ 新增了很多的加密方法~
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {

        //这些数据正常应该从数据库中读取 jdbcAuthentication()     此时是 内存中读取inMemoryAuthentication
        auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder()) //密码加密的方式
                .withUser("kuangshen").password(new BCryptPasswordEncoder().encode("123456")).roles("vip2","vip3") //编码
                .and()
                .withUser("root").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2","vip3")
                .and()
                .withUser("guest").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1");

    }
}

 RouterController

@Controller
public class RouterController {

    @RequestMapping({"/","/index"})
    public String toIndex(){
        return "index";
    }

    @RequestMapping("/toLogin")
    public String toLogin(){
        return "views/login";
    }

    @RequestMapping("/level1/{id}")
    public String toLevel1(@PathVariable("id")Integer id){
        return "views/level1/"+id;
    }

    @RequestMapping("/level2/{id}")
    public String toLevel2(@PathVariable("id")Integer id){
        return "views/level2/"+id;
    }

    @RequestMapping("/level3/{id}")
    public String toLevel3(@PathVariable("id")Integer id){
        return "views/level3/"+id;
    }

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
您好!对于未授权的springboot-actuator,您可以尝试以下解决方案: 1. 检查配置文件:确保您的应用程序的配置文件中已正确配置了安全认证。您可以在application.properties或application.yml文件中查找以下配置项: management.security.enabled=true 如果该配置项已启用,并且您仍然遇到未授权的问题,请继续尝试下一个解决方案。 2. 添加访问权限:您可以为actuator端点添加访问权限。在您的配置文件中添加以下配置来设置允许访问的角色: management.endpoints.web.exposure.include=* management.endpoint.health.roles=ACTUATOR_ADMIN 这将允许所有角色访问所有的actuator端点。您可以根据需要更改角色名称或将其限制为特定角色。 3. 自定义安全配置:如果默认的安全配置不适用于您的需求,您可以自定义Spring Security配置。创建一个类,继承自WebSecurityConfigurerAdapter,并重写configure方法。在该方法中,您可以定义自己的安全规则和访问规则。 例如,您可以创建一个类似于以下示例的配置: ```java @Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/actuator/**").hasRole("ACTUATOR_ADMIN") .anyRequest().authenticated() .and() .httpBasic(); } } ``` 这将要求用户在访问actuator端点时进行身份验证,并且只有具有ACTUATOR_ADMIN角色的用户才能访问。 请注意,根据您的具体需求,您可能需要调整上述解决方案的细节。希望这些提示对您有帮助!如有更多问题,请随时提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

gh-xiaohe

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值