当前位置: 首页 > news >正文

公司网站建设 阜阳/网站seo具体怎么做?

公司网站建设 阜阳,网站seo具体怎么做?,安卓aso关键词优化,如何提高百度权重Spring Security官网 : https://projects.spring.io/spring-security/ Spring Security简介: Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。它提供了一组可以在Spring应用上下文中配置的Bean&#…

Spring Security官网 : https://projects.spring.io/spring-security/

Spring Security简介:

Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。它提供了一组可以在Spring应用上下文中配置的Bean,充分利用了Spring IoC,DI(控制反转Inversion of Control ,DI:Dependency Injection 依赖注入)和AOP(面向切面编程)功能,为应用系统提供声明式的安全访问控制功能,减少了为企业系统安全控制编写大量重复代码的工作。

spring security认证:

Basic:

客户端以“ : ”连接用户名和密码后,再经BASE64加密通过Authorization请求头发送该密文至服务端进行验证,每次请求都需要重复发送该密文。可见Basic认证过程简单,安全性也低,存在泄露个人账号信息以及其他诸多安全问题。

Digest:

TTP协议规范的另一种认证模式是Digest模式,在HTTP1.1时被提出来,它主要是为了解决Basic模式安全问题,用于替代原来的Basic认证模式,Digest认证也是采用challenge/response认证模式,基本的认证流程比较类似,整个过程如下:

①浏览器发送http报文请求一个受保护的资源。

②服务端的web容器将http响应报文的响应码设为401,响应头部比Basic模式复杂,WWW-Authenticate: Digest realm=”myTomcat”,qop="auth",nonce="xxxxxxxxxxx",opaque="xxxxxxxx" 。其中qop的auth表示鉴别方式;nonce是随机字符串;opaque服务端指定的值,客户端需要原值返回。

③浏览器弹出对话框让用户输入用户名和密码,浏览器对用户名、密码、nonce值、HTTP请求方法、被请求资源URI等组合后进行MD5运算,把计算得到的摘要信息发送给服务端。请求头部类似如下,Authorization: Digest username="xxxxx",realm="myTomcat",qop="auth",nonce="xxxxx",uri="xxxx",cnonce="xxxxxx",nc=00000001,response="xxxxxxxxx",opaque="xxxxxxxxx" 。其中username是用户名;cnonce是客户端生成的随机字符串;nc是运行认证的次数;response就是最终计算得到的摘要。

④服务端web容器获取HTTP报文头部相关认证信息,从中获取到username,根据username获取对应的密码,同样对用户名、密码、nonce值、HTTP请求方法、被请求资源URI等组合进行MD5运算,计算结果和response进行比较,如果匹配则认证成功并返回相关资源,否则再执行②,重新进行认证。

⑤以后每次访问都要带上认证头部。

X.509:

X.509格式证书是被广泛使用的数字证书标准,是用于标志通讯各方身份信息的一系列数据。

LDAP:

和利用数据库进行验证类似,LDAP中也是利用登陆名和密码进行验证,LDAP中会定义一个属性password,用来存放用户密码,而登陆名使用较多的都是mail地址。那怎么样才能正确的用LDAP进行身份验证呢,下面是一个正确而又通用的步骤:

1. 从客户端得到登陆名和密码。注意这里的登陆名和密码一开始并没有被用到。

2. 先匿名绑定到LDAP服务器,如果LDAP服务器没有启用匿名绑定,一般会提供一个默认的用户,用这个用户进行绑定即可。

3. 之前输入的登陆名在这里就有用了,当上一步绑定成功以后,需要执行一个搜索,而filter就是用登陆名来构造,形如: "(|(uid=$login)(mail=$login))" ,这里的login就是登陆名。搜索执行完毕后,需要对结果进行判断,如果只返回一个entry,这个就是包含了该用户信息的entry,可以得到该entry的DN,后面使用。如果返回不止一个或者没有返回,说明用户名输入有误,应该退出验证并返回错误信息。

4. 如果能进行到这一步,说明用相应的用户,而上一步执行时得到了用户信息所在的entry的DN,这里就需要用这个DN和第一步中得到的password重新绑定LDAP服务器。

5. 执行完上一步,验证的主要过程就结束了,如果能成功绑定,那么就说明验证成功,如果不行,则应该返回密码错误的信息。

这5大步就是基于LDAP的一个 “两次绑定” 验证方法。

Form:

上面介绍的几种模式都属于HTTP协议规范范畴,由于它的规范使得很多东西无法自定义,例如登录窗口、错误展示页面。所以需要另外一种模式提供更加灵活的认证,也就是基于Form的认证模式。

Form模式的认证流程如下:

①浏览器发送http报文请求一个受保护的资源。

②服务端的web容器判断此uri为受保护资源,于是将请求重定向到自定义的登陆页面上,例如login.html页面,可以自定义登陆页面的样式,但要遵守的约定是表单的action必须以j_security_check结尾,即<form action='xxxxxx/j_security_check' method='POST'>。用户名和密码输入框元素的name必须为'j_username' 和'j_password'。

③浏览器展示自定义的登陆页面让用户输入用户名和密码,然后提交表单。

④服务端web容器获取表单的用户名和密码,匹配此用户名与密码是否正确,是否有相应资源的权限,如果认证成功则返回相关资源,否则再执行②,重新进行认证。

⑤后面在同个会话期间的访问都不用再进行认证,因为认证的结果已经保存在服务端的session里面。     

Form模式跳出了HTTP规范提供了自定义的更加灵活的认证模式,但由于Form模式属于J2EE范畴,一般出现在java体系中,而且它也存在密码明文传输安全问题。

 

 

Spring Security的几个Filter

       Spring Security已经定义了一些Filter,不管实际应用中你用到了哪些,它们应当保持如下顺序。

       (1)ChannelProcessingFilter,如果你访问的channel错了,那首先就会在channel之间进行跳转,如http变为https。

       (2)SecurityContextPersistenceFilter,这样的话在一开始进行request的时候就可以在SecurityContextHolder中建立一个SecurityContext,然后在请求结束的时候,任何对SecurityContext的改变都可以被copy到HttpSession。

       (3)ConcurrentSessionFilter,因为它需要使用SecurityContextHolder的功能,而且更新对应session的最后更新时间,以及通过SessionRegistry获取当前的SessionInformation以检查当前的session是否已经过期,过期则会调用LogoutHandler。

       (4)认证处理机制,如UsernamePasswordAuthenticationFilter,CasAuthenticationFilter,BasicAuthenticationFilter等,以至于SecurityContextHolder可以被更新为包含一个有效的Authentication请求。

       (5)SecurityContextHolderAwareRequestFilter,它将会把HttpServletRequest封装成一个继承自HttpServletRequestWrapper的SecurityContextHolderAwareRequestWrapper,同时使用SecurityContext实现了HttpServletRequest中与安全相关的方法。

       (6)JaasApiIntegrationFilter,如果SecurityContextHolder中拥有的Authentication是一个JaasAuthenticationToken,那么该Filter将使用包含在JaasAuthenticationToken中的Subject继续执行FilterChain。

       (7)RememberMeAuthenticationFilter,如果之前的认证处理机制没有更新SecurityContextHolder,并且用户请求包含了一个Remember-Me对应的cookie,那么一个对应的Authentication将会设给SecurityContextHolder。

       (8)AnonymousAuthenticationFilter,如果之前的认证机制都没有更新SecurityContextHolder拥有的Authentication,那么一个AnonymousAuthenticationToken将会设给SecurityContextHolder。

       (9)ExceptionTransactionFilter,用于处理在FilterChain范围内抛出的AccessDeniedException和AuthenticationException,并把它们转换为对应的Http错误码返回或者对应的页面。

       (10)FilterSecurityInterceptor,保护Web URI,并且在访问被拒绝时抛出异常。

 

 与数据库管理不同的是,Spring Security提供了一个实现了可以缓存UserDetailService的实现类,这个类的名字是CachingUserDetailsService

该类的构造接收了一个用于真正加载UserDetails的UserDetailsService实现类,当需要加载UserDetails时,会首先从缓存中获取。如果缓存中没有对应的UserDetails,则使用UserDetailsService实现类进行加载,然后将加载后的结果存在缓存中。UserDetais与缓存的交互是通过UserCache实现的。CachingUserDetailsService默认有一个UserCache的空引用。

Spring的决策管理器,其接口为AccessDecisionManager,抽象类为AbstractAccessDecisionManager。而我们要自定义决策管理器的话一般是继承抽象类而不去直接实现接口。

在Spring中引入了投票器(AccessDecisionVoter)的概念,有无权限访问的最终觉得权是由投票器来决定的,最常见的投票器为RoleVoter,在RoleVoter中定义了权限的前缀,先看下Spring在RoleVoter中是怎么处理授权的。

public int vote(Authentication authentication, Object object, Collection<ConfigAttribute> attributes) {  int result = ACCESS_ABSTAIN;  Collection<? extends GrantedAuthority> authorities = extractAuthorities(authentication);  for (ConfigAttribute attribute : attributes) {  if (this.supports(attribute)) {  result = ACCESS_DENIED;  // Attempt to find a matching granted authority  for (GrantedAuthority authority : authorities) {  if (attribute.getAttribute().equals(authority.getAuthority())) {  return ACCESS_GRANTED;  }  }  }  }  return result;  
}  Collection<? extends GrantedAuthority> extractAuthorities(Authentication authentication) {  return authentication.getAuthorities();  
}  

Authentication中是用户及用户权限信息,attributes是访问资源需要的权限,然后循环判断用户是否有访问资源需要的权限,如果有就返回ACCESS_GRANTED,通俗的说就是有权限。

Spring提供了3个决策管理器,至于这三个管理器是如何工作的请查看SpringSecurity源码

AffirmativeBased 一票通过,只要有一个投票器通过就允许访问

ConsensusBased 有一半以上投票器通过才允许访问资源

UnanimousBased 所有投票器都通过才允许访问

下面来实现一个简单的自定义决策管理器,这个决策管理器并没有使用投票器

public class DefaultAccessDecisionManager extends AbstractAccessDecisionManager {  public void decide( Authentication authentication, Object object,   Collection<ConfigAttribute> configAttributes)   throws AccessDeniedException, InsufficientAuthenticationException{  SysUser user = (SysUser)authentication.getPrincipal();  logger.info("访问资源的用户为"+user.getUsername());  //如果访问资源不需要任何权限则直接通过  if( configAttributes == null ) {  return ;  }  Iterator<ConfigAttribute> ite = configAttributes.iterator();  //遍历configAttributes看用户是否有访问资源的权限  while( ite.hasNext()){  ConfigAttribute ca = ite.next();  String needRole = ((SecurityConfig)ca).getAttribute();  //ga 为用户所被赋予的权限。 needRole 为访问相应的资源应该具有的权限。  for( GrantedAuthority ga: authentication.getAuthorities()){  if(needRole.trim().equals(ga.getAuthority().trim())){  return;  }  }  }  throw new AccessDeniedException("");  }  
}  

 

可以直接在Spring官网生成带Web和Security的基于Maven管理的Spring Boot项目,

下载项目,创建 SpringSecurityConfig 类继承 WebSecurityConfigurerAdapter 类,

SpringSecurityConfig类中设置放开静态资源,设置Http请求的拦截,

@Configuration
@EnableWebSecurity//打开web支持
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
/*** 设置http请求放开与拦截* @param http* @throws Exception*/@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().antMatchers("/").permitAll()//根目录可以直接访问.anyRequest().authenticated()//其他路径不能直接访问
                .and().logout().permitAll()//注销任何权限都可以访问
                .and().formLogin();//允许表单登录http.csrf().disable();//关闭默认的csrf的认证
    }/*** 设置静态资源放开* @param web* @throws Exception*/@Overridepublic void configure(WebSecurity web) throws Exception {web.ignoring().antMatchers("/js/**", "/css/**", "/images/**");
    }
}

 

简单的登录功能:

在  SpringSecurityConfig  类中

    @Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {
//        设置可以登录的用户名和密码auth.inMemoryAuthentication().withUser("admin").password("123456").roles("ADMIN");}

这样在需要登录的,没有放行的功能中就需输入以上用户名和密码才可以进入。

这样可以设置多个用户和不同的权限。

    @Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {
//        设置可以登录的用户名和密码auth.inMemoryAuthentication().withUser("admin").password("123456").roles("ADMIN");auth.inMemoryAuthentication().withUser("zhangsan").password("zhangsan").roles("ADMIN");auth.inMemoryAuthentication().withUser("demo").password("demo").roles("USER");}

给方法设置权限:

   @PreAuthorize("hasRole('ROLE_ADMIN')")@RequestMapping("/roleAuth")public String role() {return "admin auth";}

这样User权限的用户demo就不能访问该方法,只有admin角色的用户可以访问。

也可以从数据库中获取用户和权限信息:

定义MyUserService类,实现UserDetailsService接口,使用去提供的loadUserByUsername方法:

    @Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {return null;}
    @Autowiredprivate MyUserService myUserService;@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {
//        设置可以登录的用户名和密码
//        auth.inMemoryAuthentication().withUser("admin").password("123456").roles("ADMIN");
//        auth.inMemoryAuthentication().withUser("zhangsan").password("zhangsan").roles("ADMIN");
//        auth.inMemoryAuthentication().withUser("demo").password("demo").roles("USER");
//
        auth.userDetailsService(myUserService).passwordEncoder(new MyPasswordEncoder());//使用自己定义的验证器//默认的Security数据库验证,如果使用,需要使用给定的数据库表结构auth.jdbcAuthentication().usersByUsernameQuery("").authoritiesByUsernameQuery("").passwordEncoder(new MyPasswordEncoder());}

 

 

定义自己的密码验证规则:

public class MyPasswordEncoder implements PasswordEncoder {private final static String SALT = "123456";/*** 密码加密* @param rawPassword* @return*/@Overridepublic String encode(CharSequence rawPassword) {Md5PasswordEncoder encoder = new Md5PasswordEncoder();return encoder.encodePassword(rawPassword.toString(), SALT);}/*** 密码匹配* @param rawPassword* @param encodedPassword* @return*/@Overridepublic boolean matches(CharSequence rawPassword, String encodedPassword) {Md5PasswordEncoder encoder = new Md5PasswordEncoder();return encoder.isPasswordValid(encodedPassword, rawPassword.toString(), SALT);}
}

 

基于表达式的权限控制

    @PreAuthorize("#id<10 and principal.username.equals(#username) and #user.username.equals('abc')")@PostAuthorize("returnObject%2==0")//返回的值是偶数,对2取余为0,此注解用于对返回值进行过滤,在方法完成后进行权限检查@RequestMapping("/test")public Integer test(Integer id, String username, User user) {// ...return id;}@PreFilter("filterObject%2==0")//传入的过滤@PostFilter("filterObject%4==0")//返回的过滤@RequestMapping("/test2")public List<Integer> test2(List<Integer> idList) {// ...return idList;}

 

总结:

优点:

1.提供了一套可用的安全框架

2.提供了很多用户认证功能,实现相关接口即可,节约了大量工作

3.基于Spring,易于集成到Spring项目中去,封装了许多方法

缺点:

1.配置文件过多,角色被“编码”到配置文件和源文件中,RBAC不明显

2.对于系统中的用户、角色、权限没有可操作的界面

3.大数据量的情况下几乎不可用

 

转载于:https://www.cnblogs.com/jiangwz/p/9133160.html

http://www.lbrq.cn/news/969445.html

相关文章:

  • 网站建设和seo讲师要求/百度风云榜电视剧排行榜
  • 做网站放什么/地方网站建设
  • 哪些网站可以接工程做/seo搜索引擎优化知乎
  • WordPress的/seo接单
  • 网站建设公司上海做网站公司排名/网址域名注册信息查询
  • 最专业网站建设公司哪家好/爱站网长尾挖掘工具
  • dreamweaver制作网站教程/seo基础知识
  • 做公众号推送的网站/社群营销活动策划方案
  • 网站 成功案例/成都seo优化
  • 建设建设网站的/广告公司接单软件
  • 做博物馆网站最重要性/东莞百度快速排名优化
  • 做ppt的网站兼职/公司seo是什么职位
  • wordpress 浏览次数/八宿县网站seo优化排名
  • 制作收费网站要花多少钱/郑州网络推广团队
  • 做外贸要建什么网站/搜狗搜索引擎网页
  • 网站开发毕设论文/深圳seo推广
  • 启迪网站建设/海外营销公司
  • 做视频挣钱的网站/网络运营培训课程
  • 用服务器ip做网站/单页网站seo优化
  • 时尚网站欣赏/淘宝直通车推广怎么做
  • 做网站用的hu软件/苏州seo服务
  • 做织梦网站时图片路径显示错误/湖北seo诊断
  • wordpress.短视频主题/百度网络优化
  • 中国菲律宾南海事件/优化排名案例
  • 做网站需要的电脑配置/seo长尾关键词排名
  • 网站内图片变换怎么做/武汉seo外包平台
  • 零基础网络工程师培训/正规seo排名多少钱
  • 杨永生的设计风格/万词霸屏百度推广seo
  • 企业信息系统架构/如何做好搜索引擎优化工作
  • 广东政府网站集约化平台/希爱力
  • NTC电阻防浪涌介绍
  • 042_封装的实现(属性私有化 / 方法公开)
  • PDF 转 Word 支持加密的PDF文件转换 批量转换 编辑排版自由
  • 智慧农业新图景:物联网如何精准守护作物生长​
  • 前端网络性能优化
  • ESP32S3+VSCode+PlatformIO+Arduino+Freertos开发入门指南:基于Arduino框架的应用开发全流程