Spring Security框架(三)

spring-security

之前的用户的账号、密码、权限都是在配置文件中写死了。
那么从数据库中获取呢?

从数据库查询用户信息
如果我们要从数据库动态查询用户信息,就必须按照spring security框架的要求提供一个实现UserDetailsService接口的实现类,并按照框架的要求进行配置即可。框架会自动调用实现类中的方法并自动进行密码校验。

实现步骤:

  1. 创建一个类实现UserDetailsService接口
import com.anone.pojo.User;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import java.util.ArrayList;
import java.util.List;

public class SpringSecurityUserService implements UserDetailsService {
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        //1.根据用户名查询数据库,获得User
        User user = findUserByUname(username);
        //2.判断是否为null
        if (user == null) {
            return null;
        }
        //3.把用户名,数据库的密码,以及查询出来的权限访问,创建UserDetails对象返回
        List<GrantedAuthority> list = new ArrayList<GrantedAuthority>();//先把角色和权限写死,后面从数据库查询出来
        list.add(new SimpleGrantedAuthority("add"));
        list.add(new SimpleGrantedAuthority("delete"));
        list.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
        org.springframework.security.core.userdetails.User userDetails = new org.springframework.security.core.userdetails.User(username, "{noop}"+user.getPassword(), list);
        return userDetails;
    }
    //模拟从数据库查询
    private User findUserByUname(String username) {
        if ("admin".equals(username)) {
            User user = new User();
            user.setUsername(username);
            user.setPassword("123456");
            return user;
        }
        return null;
    }
}

2.在spring-security.xml进行配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:security="http://www.springframework.org/schema/security"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                            http://www.springframework.org/schema/beans/spring-beans.xsd
                            http://www.springframework.org/schema/mvc
                            http://www.springframework.org/schema/mvc/spring-mvc.xsd
                            http://code.alibabatech.com/schema/dubbo
                            http://code.alibabatech.com/schema/dubbo/dubbo.xsd
                            http://www.springframework.org/schema/context
                            http://www.springframework.org/schema/context/spring-context.xsd
                            http://www.springframework.org/schema/security
                            http://www.springframework.org/schema/security/spring-security.xsd">
         <security:http security="none" pattern="/login.html" /> 
    <!--1.配置需要权限才能访问的资源
             auto-config属性: true 自动配置
             use-expressions属性: false 不使用表达式
    -->
<security:http auto-config="true" use-expressions="false">
       ...
    <!--配置自定义登录页面
            login-page: 登录页面; username-parameter:指定用户名的name;
            password-parameter:指定密码的name;login-processing-url:指定登录的action;
            authentication-failure-url:认证失败跳转的页面
            authentication-success-forward-url:指定登录成功跳转的页面【默认是之前访问什么页面,登录成功后就跳转什么页面】
   -->
   <security:http auto-config="true" use-expressions="false">
    ...
    <!--配置退出登录
            logout-url:配置退出登录的路径; logout-success-url:配置成功退出登录后,跳转的页面;
            invalidate-session:退出登录时销毁session
        -->
    <security:logout logout-url="/logout.do" logout-success-url="/login.html" invalidate-session="true"/>
</security:http>
    <security:form-login
                         login-page="/login.html"
                         username-parameter="username"
                         password-parameter="password"
                         login-processing-url="/login.do"
                         authentication-failure-url="/login.html"
                         authentication-success-forward-url="/index.html"
                         />
</security:http>
<!--关闭CsrfFilter过滤器-->
<security:http auto-config="true" use-expressions="false">
    <security:csrf disabled="true"/>
</security:http>
   <!--.配置认证管理器-->
<security:authentication-manager>
    <security:authentication-provider user-service-ref="springSecurityUserService">
    </security:authentication-provider>
</security:authentication-manager>
<bean id="springSecurityUserService" class="com.itheima.security.SpringSecurityUserService"></bean>
</beans>

运行启动maven的Tomcat插件即可。

对密码进行加密

实现步骤:

  1. 注册bcrypt对象, 告诉SpringSecurity使用这个加密方式
<!--.配置认证管理器-->
<security:authentication-manager>
    <!--使用自定义的认证提供者-->
    <security:authentication-provider user-service-ref="springSecurityUserService">
        <!--指定密码加密码策略-->
        <security:password-encoder ref="bCryptPasswordEncoder"/>
    </security:authentication-provider>
</security:authentication-manager>
<!--注册密码加密对象-->
<bean id="bCryptPasswordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>
  1. 注入到代码里面 即可使用
在SpringSecurityUserService中注入

 @Autowired
 private BCryptPasswordEncoder encoder;
当我们使用的时候,它会自动加盐(底层是这样的,可以自行去看源码)


spring security其他的配置

配置多种校验规则
通过配置文件的形式来设置权限
修改spring-security.xml文件:

<!--只要认证通过就可以访问-->
<security:intercept-url pattern="/index.jsp"  access="isAuthenticated()" />
<security:intercept-url pattern="/a.html"  access="isAuthenticated()" />
<!--拥有add权限就可以访问b.html页面-->
<security:intercept-url pattern="/b.html"  access="hasAuthority('add')" />
<!--拥有ROLE_ADMIN角色就可以访问c.html页面-->
<security:intercept-url pattern="/c.html"  access="hasRole('ROLE_ADMIN')" />
<!--拥有ROLE_ADMIN角色就可以访问d.html页面,
    注意:此处虽然写的是ADMIN角色,框架会自动加上前缀ROLE_-->

注解方式权限控制
Spring Security除了可以在配置文件中配置权限校验规则,还可以使用注解方式控制类中方法的调用。

实现步骤:

开启权限注解支持
在Controller的方法上面添加@PreAuthorize

第一步:在spring-security.xml文件中配置组件扫描,用于扫描Controller

<mvc:annotation-driven></mvc:annotation-driven>
<context:component-scan base-package="com.anone.controller"></context:component-scan>

第二步:在spring-security.xml文件中开启权限注解支持

<!--开启注解方式权限控制-->
<security:global-method-security pre-post-annotations="enabled" />

第三步:创建Controller类并在Controller的方法上加入注解进行权限控制

import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/hello")
public class HelloController {
    @RequestMapping("/add")
    @PreAuthorize("hasAuthority('add')")//表示用户必须拥有add权限才能调用当前方法
    public String add(){
        System.out.println("add...");
        return null;
    }
    @RequestMapping("/delete")
    @PreAuthorize("hasRole('ROLE_ADMIN')")//表示用户必须拥有ROLE_ADMIN角色才能调用当前方法
    public String delete(){
        System.out.println("delete...");
        return null;
    }
}

注意:

一般是认证之后可以获取访问静态页面的权限,使用配置文件的方式
控制Controller的方法 建议使用注解
基本上都是配置文件+注解开发
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值