spring security框架学习总结

1,spring security框架
1.0 概念
认证:登陆,校验用户名和密码
授权:认证成功后可以做哪儿些操作
涉及到的表:
权限模块共涉及到7张表。在这7张表中,角色表起到了至关重要的 作用,其处于核心位置,因为用户、权限、菜单都和角色是多对多关系。
认证过程:只需要用户表就可以了,在用户登录时可以查询用户表t_user进行校验,判断 用户输入的用户名和密码是否正确。
授权过程:用户必须完成认证之后才可以进行授权,首先可以根据用户查询其角色,再 根据角色查询对应的菜单,这样就确定了用户能够看到哪些菜单。然后再根据用户的角 色查询对应的权限,这样就确定了用户拥有哪些权限。所以授权过程会用到上面7张表。

在这里插入图片描述

1.1 入门案例
引入坐标:

org.springframework.security
spring-security-core
5.0.5.RELEASE



org.springframework.security
spring-security-config
5.0.5.RELEASE



org.springframework.security
spring-security-web
5.0.5.RELEASE

配置web.xml:

springSecurityFilterChain
org.springframework.web.filter.DelegatingFilterProxy



springSecurityFilterChain
/*

DelegatingFilterProxy用于整合第三方框架
整合Spring Security时过滤器的名称必须为springSecurityFilterChain,
否则会抛出NoSuchBeanDefinitionException异常

/和/* 的区别:
/* 拦截所有的路径。包括静态资源,动态资源,jsp资源
/ 拦截除了jsp,都拦
注意: 过滤器的名称必须叫 springSecurityFilterChain
编写配置文件:
spring-security.xml

<security:http auto-config=“true” use-expressions=“true”>

<security:intercept-url pattern="/**" access=“hasRole(‘ROLE_ADMIN’)”></security:intercept-url>
</security:http>

security:authentication-manager

<security:authentication-provider >

security:user-service

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

但是入门案例中的使用方法离我们真实生产环境还差很远,还存在如下一些问题:
1、项目中我们将所有的资源(所有请求URL)都保护起来,实际环境下往往有一些资源 不需要认证也可以访问,也就是可以匿名访问。
2、登录页面是由框架生成的,而我们的项目往往会使用自己的登录页面。
3、直接将用户名和密码配置在了配置文件中,而真实生产环境下的用户名和密码往往保 存在数据库中。
4、在配置文件中配置的密码使用明文,这非常不安全,而真实生产环境下密码需要进行 加密。

1.2 问题说明
1.2.1 登陆页面使用我们自己编写的
<security:form-login login-page="/pages/login.html"
login-processing-url="/login.do"
default-target-url="/index.html"
authentication-failure-forward-url="/pages/login.html"
username-parameter=“username”
password-parameter=“password”/>

<security:csrf disabled=“true”></security:csrf>

login-page : 登陆页面的路径
login-processing-url : 登陆时提交的路径
default-target-url : 认证成功后跳转的资源
authentication-failure-forward-url : 认证失败跳转的资源路径
username-parameter : 登陆页面用户名输入框name属性的值
password-parameter : 登陆页面密码输入框name属性的值
1.2.2 有些资源我们不希望拦截
<security:http security=“none” pattern="/a.html" />
上面的配置表示访问a.html页面不需要进行认证。
以后开发中,哪儿些资源需要进行匿名访问:
<security:http security=“none” pattern="/js/" />
<security:http security=“none” pattern="/css/
" />
<security:http security=“none” pattern="/img/" />
<security:http security=“none” pattern="/images/
" />
<security:http security=“none” pattern="/plugins/**" />
<security:http security=“none” pattern="/login.html" />

1.2.3 用户名和密码不希望在配置文件中写死
配置:
security:authentication-manager

<security:authentication-provider user-service-ref=“userService”>
</security:authentication-provider>
</security:authentication-manager>

注意: SpringSecurityUserService类要求必须实现UserDetailsService接口,重写loadUserByUsername
编写SpringSecurityUserService类:
public class SpringSecurityUserService implements UserDetailsService {
//模拟数据库中的用户数据
public static Map<String, TUser> map = new HashMap<String, TUser>();
static {
TUser user1 = new TUser();
user1.setUsername(“admin”);
user1.setPassword(“admin”);//明文密码(没有加密)

TUser user2 = new TUser();
user2.setUsername(“xiaoming”);
user2.setPassword(“1234”);

map.put(user1.getUsername(),user1);
map.put(user2.getUsername(),user2);
}


//根据用户名查询用户信息
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
System.out.println(“用户输入的用户名为:” + username);
//根据用户名查询数据库获得用户信息(包含数据库中存储的密码信息)
TUser user = map.get(username);//模拟查询根据用户名查询数据库
if(user == null){
//用户名不存在
return null;
}else{
//将用户信息返回给框架
//框架会进行密码比对(页面提交的密码和数据库中查询的密码进行比对)
List list = new ArrayList();
//为当前登录用户授权,后期需要改为从数据库查询当前用户对应的权限
list.add(new SimpleGrantedAuthority(“permission_A”));//授权
list.add(new SimpleGrantedAuthority(“permission_B”));
list.add(new SimpleGrantedAuthority(“ROLE_ADMIN”));

if(username.equals(“admin”)){
list.add(new SimpleGrantedAuthority(“ROLE_ADMIN”));//授予角色
}
User securityUser = new User(username,"{noop}"+user.getPassword(),list);
return securityUser;
}
}
}

1.3 表达式的书写
hasRole(‘角色名称’) : 判断是否具有指定的角色
isAuthenticated() : 判断是否认证
hasAuthority(‘权限’) : 判断是否爱有指定的权限
hasAnyRole(String… roles) : 只要有指定的角色中的任意一个即可
hasAnyAuthority(String… authorities) : 只要有指定的权限中的任意一个即可
如何使用表达式:
<security:intercept-url pattern="/pages/**" access=“hasRole(‘ROLE_ROBIN’)”/>

1.4 注解方式权限控制(细颗粒度权限控制)
进行细颗粒度权限控制。
1,开启权限控制注解支持
<security:global-method-security pre-post-annotations=“enabled”></security:global-method-security>
2,使用注解
@RestController
@RequestMapping("/hello")
public class HelloController {

@RequestMapping("/add")
@PreAuthorize("hasAuthority('add')")//调用此方法要求当前用户必须具有add权限
public String add(){
    System.out.println("add...");
    return "success";
}

@RequestMapping("/delete")
@PreAuthorize("hasAnyRole('ROLE_ADMIN','ROLE_ROBIN')")//调用此方法要求当前用户必须具有ROLE_ADMIN角色
public String delete(){
    System.out.println("delete...");
    return "success";
}

}

spring security框架 应用

1.1 导入Spring Security环境
第一步:在health_parent父工程的pom.xml中导入Spring Security的maven坐标
第二步:在health_backend工程的web.xml文件中配置用于整合Spring Security框架的 过滤器DelegatingFilterProxy
1.2 实现认证和授权
第一步:在health_backend工程中按照Spring Security框架要求提供 SpringSecurityUserService,并且实现UserDetailsService接口
第二步:创建UserService服务接口、服务实现类、Dao接口、Mapper映射文件等
第三步:修改health_backend工程中的springmvc.xml文件,修改dubbo批量扫描的包 路径
第四步:在health_backend工程中提供spring-security.xml配置文件
第五步:在springmvc.xml文件中引入spring-security.xml文件
第六步:在Controller的方法上加入权限控制注解,此处以CheckItemController为例
第七步:修改页面,没有权限时提示信息设置,此处以checkitem.html中的 handleDelete方法为例

发布了71 篇原创文章 · 获赞 1 · 访问量 1149

猜你喜欢

转载自blog.csdn.net/weixin_44993313/article/details/103796139