使用Spring Security4做权限管理入门

步骤一:新建工程

新建一个maven工程,并使用以下依赖:或者去下载Spring Security 的jar包
<dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-core</artifactId>
            <version>4.2.2.RELEASE</version>
        </dependency>
        
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-web</artifactId>
            <version>4.2.2.RELEASE</version>
        </dependency>
        
         <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-config</artifactId>
            <version>4.2.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-taglibs</artifactId>
            <version>4.2.2.RELEASE</version>
        </dependency>
Spring Security(以下简称SS) 3 和 4 版本差异很大,这里我用的是SS4。如果搭配spring 使用,则对spring 版本也有要求,尽量用新的就行,这里我用的spring 4.2.4

步骤二:配置web.xml

Spring Security 的原理是使用了过滤器,所以我们配置SS的过滤器,好让它生效。
<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>

步骤三:加载配置文件

我把spring系的配置文件一起加载,使用如下配置
<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:spring/applicationContext*.xml</param-value>
	</context-param>
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>
这是我项目结构图,applicationContext-security.xml是SS的配置文件

步骤四:编写配置文件

首先先看我自己工程中的配置文件
<beans:beans xmlns="http://www.springframework.org/schema/security"
    xmlns:beans="http://www.springframework.org/schema/beans" 
    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">
 	<http pattern="/**/*.js" security="none" />
 	 <http pattern="/**/*.css" security="none" />
    <http use-expressions="true">
        <!-- 访问所有页面都需要有USER权限 -->
         <intercept-url pattern="/login.html" access="hasRole('ROLE_ANONYMOUS') or hasRole('ROLE_USER')" />
         <intercept-url pattern="/index.html" access="hasRole('ROLE_ANONYMOUS') or hasRole('ROLE_USER')" />
        <intercept-url pattern="/**" access="hasRole('ROLE_USER')" />
        
        <!-- 登录功能 -->
        <form-login login-page="/login.html"  default-target-url="/index.html" authentication-failure-url="/login.html?error=true" always-use-default-target="true" />
        <!-- 配置登录页面地址login-page、登录失败后的跳转地址authentication-failure-url -->
 <!--     <form-login login-page='/login.jsp' authentication-failure-url='/login.jsp?error' />-->
        <!-- 登出功能 -->
        <logout logout-url="/logout"  />
        <csrf disabled="true"/> 
    </http>
 	<!--  
    <authentication-manager>
	 <authentication-provider>
            <user-service>
                <user name="jimi" password="jimi" authorities="ROLE_USER" />
                <user name="bob" password="bob" authorities="ROLE_USER" />
            </user-service>
        </authentication-provider>
    </authentication-manager>
 -->
   <!-- Select users and user_roles from database -->
    <authentication-manager>
        <authentication-provider>
            <jdbc-user-service data-source-ref="dataSource"
                users-by-username-query="select user_id username,password password, enabled enabled from users where user_id=?"
                authorities-by-username-query="select user_id username, rightstr role from privilege where user_id=?  " />
             <password-encoder hash="md5">
             </password-encoder>
        </authentication-provider>
    </authentication-manager>
</beans:beans>
<http pattern="/**/*.js" security="none" />
表示对以.js后缀的文件完全放行,注意,是完全放行,不经过过滤器。推荐把一些静态文件用这种写法,因为如果将主页之类文件的security 置为none,将不会经过SS的过滤器, 进而无法在页面上取出任何值。(当前登录用户,当前权限等等)

 <http use-expressions="true">
意思为开启 SpEL(SS自定义的一种表达式语言),开启之后access里都要写成我上述的写法
  <intercept-url pattern="/login.html" access="hasRole('ROLE_ANONYMOUS') or hasRole('ROLE_USER')" />
表示login.html这个页面只有匿名用户和User权限的用户才能访问。
如果不开启SpEL,可以这样写:

  <intercept-url pattern="/login.html" access="ROLE_ANONYMOUS,ROLE_USER" />
我这几条的意思是,除了login.html以及index.html做了特殊处理(允许匿名用户访问),其他都要求ROLE_USER权限
  <!-- 访问所有页面都需要有USER权限 -->
         <intercept-url pattern="/login.html" access="hasRole('ROLE_ANONYMOUS') or hasRole('ROLE_USER')" />
         <intercept-url pattern="/index.html" access="hasRole('ROLE_ANONYMOUS') or hasRole('ROLE_USER')" />
        <intercept-url pattern="/**" access="hasRole('ROLE_USER')" />
登陆配置:
  <form-login login-page="/login.html"  default-target-url="/index.html" authentication-failure-url="/login.html?error=true" always-use-default-target="true" />
依次是,登陆页面的地址,登陆完跳转的地址,登陆失败时跳转的地址,是否在登陆成功后一直跳转到登陆成功页面(如果不开启,SS默认跳转到用户在登陆前正在浏览时因为权限不足被弹出来的页面)

登出路径配置:还有其他配置选项,我没有配,就配了路径
  <logout logout-url="/logout"  />
是否关闭防止csrf攻击:
 <csrf disabled="true"/> 
如果不关闭,每次post请求必须附带一个token。因为我嫌麻烦直接关掉了

这是登陆管理器:
<authentication-manager>
	 <authentication-provider>
            <user-service>
                <user name="lynn" password="lynn" authorities="ROLE_USER" />
                <user name="bob" password="bob" authorities="ROLE_USER" />
            </user-service>
        </authentication-provider>
    </authentication-manager>
如果不适用数据库做账号密码验证,可以把用户密码和拥有的权限填在这儿,但估计没人会这么做。
接下来介绍数据库式的:
 <!-- Select users and user_roles from database -->
    <authentication-manager>
        <authentication-provider>
            <jdbc-user-service data-source-ref="dataSource"
                users-by-username-query="select user_id username,password password, enabled enabled from users where user_id=?"
                authorities-by-username-query="select user_id username, rightstr role from privilege where user_id=?  " />
             <password-encoder hash="md5">
             </password-encoder>
        </authentication-provider>
    </authentication-manager>
这里需要配置一个authentication-provider,然后需要注入一个dataSource,这个是你的连接池的bean。我没有定义在这个配置文件中,你可以另外开一个applicationContext-dao 放连接池,我用的Druid连接池
	<!-- 数据库连接池 -->
	<!-- 加载配置文件 -->
	<context:property-placeholder location="classpath:conf/db.properties" />
	<!-- 数据库连接池 -->
	<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
		destroy-method="close">
		<property name="url" value="${jdbc.url}" />
		<property name="username" value="${jdbc.username}" />
		<property name="password" value="${jdbc.password}" />
		<property name="driverClassName" value="${jdbc.driver}" />
		<property name="maxActive" value="10" />
		<property name="minIdle" value="5" />
	</bean>
	<!-- 让spring管理sqlsessionfactory 使用mybatis和spring整合包中的 -->
	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
		<!-- 数据库连接池 -->
		<property name="dataSource" ref="dataSource" />
		<!-- 加载mybatis的全局配置文件 -->
		<property name="configLocation" value="classpath:mybatis/SqlMapConfig.xml" />
	</bean>
下面是sql查询语句:
 <jdbc-user-service data-source-ref="dataSource"
                users-by-username-query="select user_id username,password password, enabled enabled from users where user_id=?"
                authorities-by-username-query="select user_id username, rightstr role from privilege where user_id=?  " />
特别注意:账号列如果不是username,请起一个别名username,否则SS无法识别,同理,password和enabled也是

 <password-encoder hash="md5">
采用了md5加密,开启这个从前台传过来的密码SS会经过一次md5加密,然后跟数据库里的密码进行比对。也有其他加密方式,官方推荐使用bcrypt,这里我用了md5

步骤五:更改前台表单

 <h1 class="text-center" style="margin-bottom: 30px">用户登录</h1>
            <form class="form-horizontal caption" action="login" method="post">
                <div class="form-group">
                    <label for="username" class="col-sm-3 control-label">用户名</label>
                    <div class="col-sm-8">
                        <input type="text" class="form-control" id="username" placeholder="用户名">
                    </div>
                </div>
                <div class="form-group">
                    <label for="password" class="col-sm-3 control-label">密码</label>
                    <div class="col-sm-8">
                        <input type="password" class="form-control" id="password" placeholder="密码">
                    </div>
                </div>
                <div class="form-group">
                    <div class="col-sm-offset-3 col-sm-9">
                        <div class="checkbox">
                            <label>
                                <input type="checkbox">记住我
                            </label>
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="col-sm-offset-4 col-sm-5">
                        <button type="submit" class="btn btn-success btn-block">登录</button>
                    </div>
                </div>
            </form>
前台我用的bootstrap,这是登陆表单的代码,需要把用户名框的name设为username,把密码框的name设为password,这样SS才能检测到。表单提交的路径是SS 默认的login

步骤六:启动工程测试

当我访问problem.html时,被弹到了登陆页面,但访问index.html能正常访问(因为设置了匿名访问权限)
登陆成功:

关于如何在页面上取到当前用户信息,看我接下来的文章
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Security是一个用于身份验证和授权的框架,在Spring项目中提供了一套强大的安全性解决方案。以下是你入门Spring Security的步骤: 1. 添加Spring Security依赖:在你的项目中,通过Maven或Gradle添加Spring Security的依赖。例如,在Maven中,你可以添加以下依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> ``` 2. 配置Spring Security:创建一个配置类来配置Spring Security。这个配置类需要继承`WebSecurityConfigurerAdapter`类,并覆盖`configure`方法。例如,你可以创建一个类叫`SecurityConfig`: ```java @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/public/**").permitAll() // 允许公共访问的URL .anyRequest().authenticated() // 其他URL需要身份验证 .and() .formLogin() // 启用表单登录 .loginPage("/login") // 自定义登录页面URL .permitAll() .and() .logout() // 启用注销 .permitAll(); } } ``` 上述配置中,我们定义了哪些URL是公开访问的,哪些URL需要身份验证,以及自定义了登录和注销的相关配置。 3. 创建用户服务:在上面的配置类中,你需要定义一个用户服务来获取用户的身份验证信息。这可以通过实现`UserDetailsService`接口来完成。你可以创建一个类叫`UserService`来实现这个接口,并重写`loadUserByUsername`方法: ```java @Service public class UserService implements UserDetailsService { @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { // 从数据库或其他数据源中获取用户信息 // 然后返回一个实现了UserDetails接口的类,代表用户的身份验证信息 // 例如,你可以使用Spring Security提供的User类 return User.builder() .username(username) .password("password") .roles("USER") .build(); } } ``` 上述代码中,我们简单地返回了一个固定的用户信息,实际应用中你需要从数据库或其他数据源中获取真实的用户信息。 4. 配置密码编码器:为了安全起见,你需要对用户密码进行编码。在上述的配置类中,通过重写`configure`方法来配置密码编码器。例如: ```java @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private UserService userService; @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userService).passwordEncoder(passwordEncoder()); } // 其他配置... } ``` 上述代码中,我们使用了`BCryptPasswordEncoder`来对密码进行编码。 这些是入门Spring Security的基本步骤。当你完成了上述配置后,你的应用程序将需要进行身份验证,并且可以通过URL保护来限制访问。你可以根据需要进一步自定义和扩展Spring Security的功能。希望这能帮助到你!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值