Spring-Security的详细配置及用法01

Spring-Security是一个用于安全管理的框架,能减少自定义登录代码的工作量。配置包括:引入jar包,配置web.xml的过滤器,创建spring-security.xml文件定义拦截规则和登录逻辑,以及设定用户账号和权限。在数据库环境中,需要配置userService并实现UserDetailsService接口以从数据库获取用户信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【1】Spring-Security通俗一点来讲是用来管理我们登陆的一个框架,之前我们的登陆底层代码,都是自己手写的,要从web端获取parameter,然后从数据库中取出,再获取数据库中的账户密码,进行对比,相同的话跳转到登陆成功页面,不成功提示登陆失败。

【2】利用Spring-Security框架的目的自然就是节省代码量,而且方便管理,不需要手动获取前端数据。

【3】第一步,我们需要在pol中导入spring-security的jar包,一共四个,分别是web,config,core,和jstl需要的taglibs。

        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-web</artifactId>
            <version>${spring.security.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-config</artifactId>
            <version>${spring.security.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-core</artifactId>
            <version>${spring.security.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-taglibs</artifactId>
            <version>${spring.security.version}</version>
        </dependency>

【4】第二步,我们需要在web.xml中配置spring-security的filter,用来过滤所有文件

         注意:springSecurityFilterChain这个filter-name不能变,是固定的

、     原因:因为DelegatingFilterProxy并不是真正要执行的类,它里面有一个initFilterBean的方法,这个方法会从WebApplicationContext中根据delegate(代理)来获取到一个名叫getFilterName()的名称,而这个名称就叫做springSecurityFilterChain,而delegate其实就是FilterChainProxy,它就是spring在解析配置文件的时候装配到上下文中,并且beanname就是springSecurityFilterChain,所以这个web.xml中的名字不能变

  <!--加入spring-security的filter-->
  <filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

【5】第三步,需要写一个spring-security.xml文件。

        1 约束

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:security="http://www.springframework.org/schema/security"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/security
    http://www.springframework.org/schema/security/spring-security.xsd">

        2配置不拦截的资源(如页面的图片,登陆页面本身,js等)

  <!-- 配置不拦截的资源 -->
    <security:http pattern="/login.jsp" security="none"/>
    <security:http pattern="/failer.jsp" security="none"/>
    <security:http pattern="/css/**" security="none"/>
    <security:http pattern="/img/**" security="none"/>
    <security:http pattern="/plugins/**" security="none"/>

        3配置拦截规则,用<security>标签

          <security:intercept>的作用是配置拦截路径,以及允许通过的验证的用户是否包含access,这里面的ROLE_USER啥的可以自定义,我这里设置的是/**全部拦截,大家可以自行设置url。

          <security:form-login>里面配置登陆页面,登陆的路径,默认路径,失败路径,成功路径。这里要注意:login-page是我们登陆要跳转的页面,login-processing-url是给前端表单提供一个提交的路径,这个路径自己没有实体页面,是内置的,名字可以自己起,唯一需要注意的就是login-processing-url必须和页面的表单请求路径一致。

          <security:csrf>跨站请求伪造,这里我还没学,不过应该把他关闭,spring4默认是开启的,我们这里设置为true,把他关闭。

          <security:logout>是退出我们当前登陆的用户,里面session设置为true就会帮我们销毁登陆用户的session,logout-url:也需要我们在前端页面的注销或者退出按钮中,保持一致,例如

${pageContext.request.contextPath}/logout.do
<security:http auto-config="true" use-expressions="false">
        <!-- 配置具体的拦截的规则 pattern="请求路径的规则" access="访问系统的人,必须有ROLE_USER的角色" -->
        <security:intercept-url pattern="/**" access="ROLE_USER,ROLE_ADMIN"/>

        <!-- 定义跳转的具体的页面 -->
        <!--这里username和password不写的话就是默认值,但必须保证页面的name值是username和password-->
        <!--login-page是展示的页面,login.do是路径-->
        <security:form-login
                login-page="/login.jsp"
                login-processing-url="/login.do"
                default-target-url="/index.jsp"
                authentication-failure-url="/failer.jsp"
                authentication-success-forward-url="/pages/main.jsp"
        />

        <!-- 关闭跨域请求 -->
        <security:csrf disabled="true"/>

        <!-- 退出 -->
        <security:logout invalidate-session="true" logout-url="/logout.do" logout-success-url="/login.jsp" />

    </security:http>
<%--走到了login.do,Spring-srcurity会帮我们处理这个页面,login.do要保持一致--%>
			<form action="${pageContext.request.contextPath}/login.do" method="post">
				<div class="form-group has-feedback">
					<input type="text" name="username" class="form-control"
						placeholder="用户名"> <span
						class="glyphicon glyphicon-envelope form-control-feedback">

【6】第六步,配置我们的账号密码,无数据库情况下

         这个也是写在spring-security.xml中,写在最后面。我们在这里手动定义了用户名和密码,以及权限,这里的权限名称必须和上面的access中的一致,spring-security的检测方法首先是通过账号密码是否正确,其次验证你的权限,两个必须都满足才可以登陆成功。而密码前面加了个{noop}只是暂时的,在后面我们设置了密码加密后,就不需要这个了。这里先这么写,符合格式。

 <security:authentication-manager>
        <security:authentication-provider>
            <security:user-service>
                <security:user name="user" password="{noop}user"
                               authorities="ROLE_USER" />
                <security:user name="admin" password="{noop}admin"
                               authorities="ROLE_ADMIN" />
            </security:user-service>
        </security:authentication-provider>
    </security:authentication-manager>

 【7】第六步,配置我们的账号密码,有数据库情况下

          注意:如果根据我前面的配置,这里的配置加密方式一定要先注释上,不然怎样都不会登陆成功。

          这里我们从数据库的数据来登录,所以我们需要写入一个userService,这个userService是bean对象存入spring的名称,也就是@Resource(“userService”)。

   <!-- 切换成数据库中的用户名和密码 -->
    <security:authentication-manager>
        <!--user-service-ref获取的是我们存入的bean对象-->
        <security:authentication-provider user-service-ref="userService">
            <!-- 配置加密的方式 -->
            <!--<security:password-encoder ref="passwordEncoder"/>-->
        </security:authentication-provider>
    </security:authentication-manager>

【8】第七步,有数据库情况下,写一个userService接口,一定要继承UserDetailService,它是一个接口,用来封装进行认证的用户信息。

         在继承了UserDetailsService后,我们就写一个IUserService的实现类,重写UserDetails的方法,通过ctrl+H我们可以看到UserDetail有一个实现类user,我们就可以返回这个user。而这个user有两个构造方法,

public User(String username, String password, boolean enabled,
      boolean accountNonExpired, boolean credentialsNonExpired,
      boolean accountNonLocked, Collection<? extends GrantedAuthority> authorities) 
public User(String username, String password,
      Collection<? extends GrantedAuthority> authorities) {
   this(username, password, true, true, true, true, authorities);
}

        传入的分别是username,password,enabled(是否通行),accountNonExpired(账户是否过期),credentialsNonExpired(验证是否过期),accountNonLocked(账户是否被锁),GranteAuthority(验证权限),这里比较重要的就是验证权限,这个需要自己写一个方法,返回的是SimpleGranteAuthorty类的List集合。其实就是无数据库时的Authorities中写的字符串。也需要和access相匹配。验证权限不影响用户的登陆,但是登陆后,能否进行操作,就和这个Access有关系了。

public interface IUserService extends UserDetailsService {

}
@Service("userService")
@Transactional
public class UserServiceImpl implements IUserService {
    @Autowired
    private IUserDao iUserDao;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        UserInfo userInfo = iUserDao.findByUserName(username);
//        UserDetails有一个实现类user,user中有一个构造方法,分别是username,password,authority
        User user=new User(userInfo.getUsername(),"{noop}"+userInfo.getPassword(),
                userInfo.getStatus()==0?false:true,true,
                true,true,getAuthority(userInfo.getRoles()));
        return user;
    }
    public List<SimpleGrantedAuthority> getAuthority(List<Role> roles){
        List<SimpleGrantedAuthority> list=new ArrayList<>();
        for (Role role : roles) {
//            注意这里RoleName在数据中必须和Spring——security中的access一致。
        list.add(new SimpleGrantedAuthority("ROLE_"+role.getRoleName()));
        }

        return list;
    }
}

【9】dao层的查询,这里我就不多说了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Hpeacheng

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

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

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

打赏作者

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

抵扣说明:

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

余额充值