各位用户为了找寻关于Spring security实现登陆和权限角色控制的资料费劲了很多周折。这里教程网为您整理了关于Spring security实现登陆和权限角色控制的相关资料,仅供查阅,以下为您介绍关于Spring security实现登陆和权限角色控制的详细内容
随笔简介
1、spring版本:4.3.2.RELEASE+spring security 版本:4.1.2.RELEASE(其它不做说明) 2、所展示内容全部用注解配置 3、springmvc已经配置好,不作说明 4、会涉及到springmvc,spel,el的东西,不熟悉的同学可以先去看一下这方面内容,特别是springmvc
首先想一下,登陆需要什么,最简单的情况下,用户名,密码,然后比对数据库,如果吻合就跳转到个人页面,否则回到登陆页面,并且提示用户名密码错误。这个过程中应该还带有权限角色,并且贯穿整个会话。有了这个思路,我们只需要把数据库的用户名密码交给spring security比对,再让security进行相关跳转,并且让security帮我们把权限角色和用户名贯穿整个会话,实际上,我们只需要提供正确的用户名和密码,以及配置下security。
目录
准备工作 登陆页面 个人页面 开始配置spring security
1.启动spring security
2.配置权限
3.编写UserDetailService
首先准备数据库表
? 1 2 3 4 5 6 7CREATE
TABLE
`
user
` (
`username`
varchar
(255)
NOT
NULL
,
`
password
`
char
(255)
NOT
NULL
,
`roles` enum(
'MEMBER'
,
'MEMBER,LEADER'
,
'SUPER_ADMIN'
)
NOT
NULL
DEFAULT
'MEMBER'
,
PRIMARY
KEY
(`username`),
KEY
`username` (`username`)
) ENGINE=InnoDB
DEFAULT
CHARSET=utf8;
PS:这里注意的是roles的内容,LEADER也是MEMBER,这样做,LEADER就拥有MEMBER的权限,当然你也可以在应用里面作判断,这个后面会说到。
登陆页面
? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="sf" uri="http://www.springframework.org/tags/form"%>
<
html
>
<
head
>
<
title
>登录</
title
>
</
head
>
<
body
>
<
div
>
<
sf:form
action
=
"${pageContext.request.contextPath}/log"
method
=
"POST"
commandName
=
"user"
>
<!-- spring表单标签,用于模型绑定和自动添加隐藏的CSRF token标签 -->
<
h1
>登录</
h1
>
<
c:if
test
=
"${error==true}"
><
p
style
=
"color: red"
>错误的帐号或密码</
p
></
c:if
>
<!-- 登陆失败会显示这句话 -->
<
c:if
test
=
"${logout==true}"
><
p
>已退出登录</
p
></
c:if
>
<!-- 退出登陆会显示这句话 -->
<
sf:input
path
=
"username"
name
=
"user.username"
placeholder
=
"输入帐号"
/><
br
/>
<
sf:password
path
=
"password"
name
=
"user.password"
placeholder
=
"输入密码"
/><
br
/>
<
input
id
=
"remember-me"
name
=
"remember-me"
type
=
"checkbox"
/>
<!-- 是否记住我功能勾选框 -->
<
label
for
=
"remember-me"
>一周内记住我</
label
>
<
input
type
=
"submit"
class
=
"sumbit"
value
=
"提交"
>
</
sf:form
>
</
div
>
</
body
>
</
html
>
个人页面
? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false"%>
<%@taglib prefix="security" uri="http://www.springframework.org/security/tags" %>
<%@ taglib prefix="sf" uri="http://www.springframework.org/tags/form"%>
<
html
>
<
head
>
<
title
>欢迎你,<
security:authentication
property
=
"principal.username"
var
=
"username"
/>${username}</
title
>
<!-- 登陆成功会显示名字,这里var保存用户名字到username变量,下面就可以通过EL获取 -->
</
head
>
<
body
>
<
security:authorize
access
=
"isAuthenticated()"
><
h3
>登录成功!${username}</
h3
></
security:authorize
>
<!-- 登陆成功会显示名字 -->
<
security:authorize
access
=
"hasRole('MEMBER')"
>
<!-- MENBER角色就会显示 security:authorize标签里的内容-->
<
p
>你是MENBER</
p
>
</
security:authorize
>
<
security:authorize
access
=
"hasRole('LEADER')"
>
<
p
>你是LEADER</
p
>
</
security:authorize
>
<
sf:form
id
=
"logoutForm"
action
=
"${pageContext.request.contextPath}/logout"
method
=
"post"
>
<!-- 登出按钮,注意这里是post,get是会登出失败的 -->
<
a
href
=
"#"
onclick
=
"document.getElementById('logoutForm').submit();"
>注销</
a
>
</
sf:form
>
</
body
>
</
html
>
开始配置spring security
1.启动spring security
? 1 2 3@Order
(
2
)
public
class
WebSecurityAppInit
extends
AbstractSecurityWebApplicationInitializer{
}
继承AbstractSecurityWebApplicationInitializer,spring security会自动进行准备工作,这里@Order(2)是之前我springmvc(也是纯注解配置)和spring security一起启动出错,具体是什么我忘了,加这个让security启动在后,可以避免这个问题,如果不写@Order(2)没有错就不用管。
2.配置权限
? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38@Configuration
@EnableWebSecurity
@ComponentScan
(
"com.chuanzhi.workspace.service.impl.*"
)
public
class
WebSecurityConfig
extends
WebSecurityConfigurerAdapter{
@Autowired
private
UserDetailService userDetailService;
//如果userDetailService没有扫描到就加上面的@ComponentScan
@Override
protected
void
configure(HttpSecurity http)
throws
Exception {
http.authorizeRequests()
.antMatchers(
"/me"
).hasAnyRole(
"MEMBER"
,
"SUPER_ADMIN"
)
//个人首页只允许拥有MENBER,SUPER_ADMIN角色的用户访问
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage(
"/"
).permitAll()
//这里程序默认路径就是登陆页面,允许所有人进行登陆
.loginProcessingUrl(
"/log"
)
//登陆提交的处理url
.failureForwardUrl(
"/?error=true"
)
//登陆失败进行转发,这里回到登陆页面,参数error可以告知登陆状态
.defaultSuccessUrl(
"/me"
)
//登陆成功的url,这里去到个人首页
.and()
.logout().logoutUrl(
"/logout"
).permitAll().logoutSuccessUrl(
"/?logout=true"
)
//按顺序,第一个是登出的url,security会拦截这个url进行处理,所以登出不需要我们实现,第二个是登出url,logout告知登陆状态
.and()
.rememberMe()
.tokenValiditySeconds(
604800
)
//记住我功能,cookies有限期是一周
.rememberMeParameter(
"remember-me"
)
//登陆时是否激活记住我功能的参数名字,在登陆页面有展示
.rememberMeCookieName(
"workspace"
);
//cookies的名字,登陆后可以通过浏览器查看cookies名字
}
@Override
public
void
configure(WebSecurity web)
throws
Exception {
super
.configure(web);
}
@Override
protected
void
configure(AuthenticationManagerBuilder auth)
throws
Exception {
auth.userDetailsService(userDetailService);
//配置自定义userDetailService
}
}
3.编写UserDetailService
spring security提供给我们的获取用户信息的Service,主要给security提供验证用户的信息,这里我们就可以自定义自己的需求了,我这个就是根据username从数据库获取该用户的信息,然后交给security进行后续处理
? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36@Service
(value =
"userDetailService"
)
public
class
UserDetailService
implements
UserDetailsService {
@Autowired
private
UserRepository repository;
public
UserDetailService(UserRepository userRepository){
this
.repository = userRepository;
//用户仓库,这里不作说明了
}
public
UserDetails loadUserByUsername(String username)
throws
UsernameNotFoundException {
User user = repository.findUserByUsername(username);
if
(user==
null
)
throw
new
UsernameNotFoundException(
"找不到该账户信息!"
);
//抛出异常,会根据配置跳到登录失败页面
List<GrantedAuthority> list =
new
ArrayList<GrantedAuthority>();
//GrantedAuthority是security提供的权限类,
getRoles(user,list);
//获取角色,放到list里面
org.springframework.security.core.userdetails.User auth_user =
new
org.springframework.security.core.userdetails.User(user.getUsername(),user.getPassword(),list);
//返回包括权限角色的User给security
return
auth_user;
}
/**
* 获取所属角色
* @param user
* @param list
*/
public
void
getRoles(User user,List<GrantedAuthority> list){
for
(String role:user.getRoles().split(
","
)) {
list.add(
new
SimpleGrantedAuthority(
"ROLE_"
+role));
//权限如果前缀是ROLE_,security就会认为这是个角色信息,而不是权限,例如ROLE_MENBER就是MENBER角色,CAN_SEND就是CAN_SEND权限
}
}
}
如果你想在记住我功能有效情况下,在下次进入登陆页面直接跳到个人首页可以看一下这个控制器代码
? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22/**
* 登录页面
* @param
* @return
*/
@RequestMapping
(value =
"/"
)
public
String login(Model model,User user
,
@RequestParam
(value =
"error"
,required =
false
)
boolean
error
,
@RequestParam
(value =
"logout"
,required =
false
)
boolean
logout,HttpServletRequest request){
model.addAttribute(user);
//如果已经登陆跳转到个人首页
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if
(authentication!=
null
&&
!authentication.getPrincipal().equals(
"anonymousUser"
)&&
authentication.isAuthenticated())
return
"me"
;
if
(error==
true
)
model.addAttribute(
"error"
,error);
if
(logout==
true
)
model.addAttribute(
"logout"
,logout);
return
"login"
;
}
结果展示:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。