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

目前我们的网站正在建设中网络营销产品

目前我们的网站正在建设中,网络营销产品,佛山营销手机网站建设,网站建设托管1.简介入门JavaEE和SpringMVC :Spring Security就是通过11个Fliter进行组合管理小Demouser实体类user.type字段,0普通用户,1超级管理员,2版主补全get set tostringimplement UserDetails,重写以下方法// true: 账号未过…

1.简介入门

JavaEE和SpringMVC :Spring Security就是通过11个Fliter进行组合管理

小Demo

user实体类

  • user.type字段,0普通用户,1超级管理员,2版主

  • 补全get set tostring

  • implement UserDetails,重写以下方法

// true: 账号未过期.
@Override
public boolean isAccountNonExpired() {return true;
}// true: 账号未锁定.
@Override
public boolean isAccountNonLocked() {return true;
}// true: 凭证未过期.
@Override
public boolean isCredentialsNonExpired() {return true;
}// true: 账号可用.
@Override
public boolean isEnabled() {return true;
}//获取当前用户权限列表
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {List<GrantedAuthority> list = new ArrayList<>();list.add(new GrantedAuthority() {@Overridepublic String getAuthority() {switch (type) {case 1:return "ADMIN";default:return "USER";}}});return list;
}

UserService

unservice implement UserDetailsService

  • 重写方法loadUserByUsername

@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {return this.findUserByName(username);
}

SecurityConfig 配置类

  • extend父类WebSecurityConfigurerAdapter

  • 注入UserService

  • 重写configure(WebSecurity web),忽略静态资源的访

@Override
public void configure(WebSecurity web) throws Exception {// 忽略静态资源的访问web.ignoring().antMatchers("/resources/**");
}
  • 重写configure(AuthenticationManagerBuilder auth),这个方法主要是做认证。

  • AuthenticationManager: 认证的核心接口

  • AuthenticationManagerBuilder: 用于构建AuthenticationManager对象的工具

  • ProviderManager: AuthenticationManager接口的默认实现类

  • ProviderManager--一组-->AuthenticationProvider--每个负责-->一种认证

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {// 内置的认证规则// auth.userDetailsService(userService).passwordEncoder(new Pbkdf2PasswordEncoder("12345"));// 自定义认证规则// AuthenticationProvider: ProviderManager持有一组AuthenticationProvider,每个AuthenticationProvider负责一种认证.// 委托模式: ProviderManager将认证委托给AuthenticationProvider.auth.authenticationProvider(new AuthenticationProvider() {// Authentication: 用于封装认证信息的接口,不同的实现类代表不同类型的认证信息.@Overridepublic Authentication authenticate(Authentication authentication) throws AuthenticationException {String username = authentication.getName();String password = (String) authentication.getCredentials();User user = userService.findUserByName(username);if (user == null) {throw new UsernameNotFoundException("账号不存在!");}password = CommunityUtil.md5(password + user.getSalt());if (!user.getPassword().equals(password)) {throw new BadCredentialsException("密码不正确!");}// principal: 主要信息; credentials: 证书; authorities: 权限;return new UsernamePasswordAuthenticationToken(user, user.getPassword(), user.getAuthorities());}// 当前的AuthenticationProvider支持哪种类型的认证.@Overridepublic boolean supports(Class<?> aClass) {// UsernamePasswordAuthenticationToken: Authentication接口的常用的实现类.return UsernamePasswordAuthenticationToken.class.equals(aClass);}});
}
  • 重写configure(HttpSecurity http)

配置登陆页面http.formLogin()

登录成功处理器.successHandler

登录失败处理器.failureHandler

退出相关配置http.logout()

授权配置http.authorizeRequests()

验证码在验证账号之前

 @Override
protected void configure(HttpSecurity http) throws Exception {// 登录相关配置http.formLogin().loginPage("/loginpage").loginProcessingUrl("/login").successHandler(new AuthenticationSuccessHandler() {@Overridepublic void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {response.sendRedirect(request.getContextPath() + "/index");}}).failureHandler(new AuthenticationFailureHandler() {@Overridepublic void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) throws IOException, ServletException {request.setAttribute("error", e.getMessage());request.getRequestDispatcher("/loginpage").forward(request, response);}});// 退出相关配置http.logout().logoutUrl("/logout").logoutSuccessHandler(new LogoutSuccessHandler() {@Overridepublic void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {response.sendRedirect(request.getContextPath() + "/index");}});// 授权配置http.authorizeRequests().antMatchers("/letter").hasAnyAuthority("USER", "ADMIN").antMatchers("/admin").hasAnyAuthority("ADMIN").and().exceptionHandling().accessDeniedPage("/denied");// 增加Filter,处理验证码http.addFilterBefore(new Filter() {@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {HttpServletRequest request = (HttpServletRequest) servletRequest;HttpServletResponse response = (HttpServletResponse) servletResponse;if (request.getServletPath().equals("/login")) {String verifyCode = request.getParameter("verifyCode");if (verifyCode == null || !verifyCode.equalsIgnoreCase("1234")) {request.setAttribute("error", "验证码错误!");request.getRequestDispatcher("/loginpage").forward(request, response);//转发return;}}// 让请求继续向下执行.filterChain.doFilter(request, response);}}, UsernamePasswordAuthenticationFilter.class);// 记住我http.rememberMe().tokenRepository(new InMemoryTokenRepositoryImpl()).tokenValiditySeconds(3600 * 24).userDetailsService(userService);}

HomeController

在首页添加欢迎信息,通过SecurityContextHolder获取登陆者信息

@RequestMapping(path = "/index", method = RequestMethod.GET)
public String getIndexPage(Model model) {// 认证成功后,结果会通过SecurityContextHolder存入SecurityContext中.Object obj = SecurityContextHolder.getContext().getAuthentication().getPrincipal();if (obj instanceof User) {model.addAttribute("loginUser", obj);}return "/index";
}

2.权限控制

  • 废除原有的拦截器

config.WebMvcConfig 种注释掉两部分

@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(loginTicketInterceptor).excludePathPatterns("/**/*.css", "/**/*.js", "/**/*.png", "/**/*.jpg", "/**/*.jpeg");// registry.addInterceptor(loginRequiredInterceptor)//         .excludePathPatterns("/**/*.css", "/**/*.js", "/**/*.png", "/**/*.jpg", "/**/*.jpeg");registry.addInterceptor(messageInterceptor).excludePathPatterns("/**/*.css", "/**/*.js", "/**/*.png", "/**/*.jpg", "/**/*.jpeg");}
  • 配置授权SecurityConfig

  1. 重写configure(HttpSecurity http),忽略对静态资源的拦截

  1. 重写configure(HttpSecurity http)http.authorizeRequests()进行授权

  1. .antMatchers:登陆后可访问路径

  1. hasAnyAuthority:可以访问的权限

  1. .anyRequest().permitAll():其他请求都允许

  1. http.exceptionHandling():越权行为发生时

  1. 覆盖它默认的logout逻辑,才能执行我们自己的退出代码

@Override
protected void configure(HttpSecurity http) throws Exception {// 授权http.authorizeRequests().antMatchers("/user/setting","/user/upload","/discuss/add","/comment/add/**","/letter/**","/notice/**","/like","/follow","/unfollow").hasAnyAuthority(AUTHORITY_USER,AUTHORITY_ADMIN,AUTHORITY_MODERATOR).anyRequest().permitAll()// 权限不够时的处理http.exceptionHandling().authenticationEntryPoint(new AuthenticationEntryPoint() {// 没有登录@Overridepublic void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) throws IOException, ServletException {String xRequestedWith = request.getHeader("x-requested-with");if ("XMLHttpRequest".equals(xRequestedWith)) {response.setContentType("application/plain;charset=utf-8");PrintWriter writer = response.getWriter();writer.write(CommunityUtil.getJSONString(403, "你还没有登录哦!"));} else {response.sendRedirect(request.getContextPath() + "/login");}}}).accessDeniedHandler(new AccessDeniedHandler() {// 权限不足@Overridepublic void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException e) throws IOException, ServletException {String xRequestedWith = request.getHeader("x-requested-with");if ("XMLHttpRequest".equals(xRequestedWith)) {response.setContentType("application/plain;charset=utf-8");PrintWriter writer = response.getWriter();writer.write(CommunityUtil.getJSONString(403, "你没有访问此功能的权限!"));} else {response.sendRedirect(request.getContextPath() + "/denied");}}});// Security底层默认会拦截/logout请求,进行退出处理.// 覆盖它默认的逻辑,才能执行我们自己的退出代码.http.logout().logoutUrl("/securitylogout");
}
  • UserService增加用户权限

public Collection<? extends GrantedAuthority> getAuthorities(int userId) {User user = this.findUserById(userId);List<GrantedAuthority> list = new ArrayList<>();list.add(new GrantedAuthority() {@Overridepublic String getAuthority() {switch (user.getType()) {case 1:return AUTHORITY_ADMIN;case 2:return AUTHORITY_MODERATOR;default:return AUTHORITY_USER;}}});return list;
}
  • 修改LoginTicketInterceptor

BUG: 登陆后点击其他需要授权的页面 依然会跳转到登录页面?
问题:在 afterCompletion
@RequestMapping(path = "/logout", method = RequestMethod.GET)
public String logout(@CookieValue("ticket") String ticket) {
userService.logout(ticket);
SecurityContextHolder.clearContext();
return "redirect:/login";
}
原因:security包括认证和授权,授权是根据认证的结果来进行的。
这里我们没有使用框架的认证,而采用自己的认证:其实就是保存一下用户的权限,就是将user信息存入 ThreadLocal 和
SecurityContextHolder.setContext
第一次login之后,已经经过interceptor了,请求处理完后 会执行SecurityContextHolder.clearContext() ,会清除user信息。下次再访问有权限的路径,就需要认证,但此时还没有用户信息,所以需要登录。

preHandle

将得到的结果存入SecurityContext

@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {//从cookie获取 ticket封装好cookieString ticket = CookieUtil.getValue(request,"ticket");  //登录时 返回了Cookie cookie = new Cookie("ticket",map.get("tivket").toString());if(ticket != null){//查询 登陆凭证ticketLoginTicket loginTicket = userService.findLoginTicket(ticket);//判断是否有效+否过期if(loginTicket != null &&loginTicket.getStatus() == 0 &&loginTicket.getExpired().after(new Date())){//根据 loginTicket 查询用户User user = userService.findUserById(loginTicket.getUserId());//把用户信息 暂存  每个浏览器访问服务器时 服务器会创建单独的线程来执行请求 即多线程的环境 考虑线程隔离;hostHolder.setUser(user);// 构建用户认证的结果,并存入SecurityContext,以便于Security进行授权.Authentication authentication = new UsernamePasswordAuthenticationToken(user, user.getPassword(), userService.getAuthorities(user.getId()));SecurityContextHolder.setContext(new SecurityContextImpl(authentication));System.out.println(SecurityContextHolder.getContext());}}return true;}
  • LoginController

@RequestMapping(path = "/logout", method = RequestMethod.GET)
public String logout(@CookieValue("ticket") String ticket) {userService.logout(ticket);SecurityContextHolder.clearContext();return "redirect:/login";
}

3.加精 置顶 删除

  • DAODiscussPostMapper添加 修改类型 状态 的方法

  • 完善对应的Mapper.xml

  • DiscussPostController

置顶请求

@RequestMapping(path = "/top", method = RequestMethod.POST)@ResponseBodypublic String setTop(int id){DiscussPost discussPostById = discussPostService.findDiscussPostById(id);// 获取置顶状态,1为置顶,0为正常状态,1^1=0 0^1=1int type = discussPostById.getType()^1;discussPostService.updateType(id, type);// 返回的结果Map<String, Object> map = new HashMap<>();map.put("type", type);// 触发发帖事件(更改帖子状态)Event event = new Event().setTopic(TOPIC_PUBLISH).setUserId(hostHolder.getUser().getId()).setEntityType(ENTITY_TYPE_POST).setEntityId(id);eventProducer.fireEvent(event);return CommunityUtil.getJSONString(0, null, map);}

加精类似

删除 直接将status 改为 2(拉黑 不显示)

  • 配置 SecurityConfig 权限情况

                .antMatchers("/discuss/top","/discuss/wonderful").hasAnyAuthority(AUTHORITY_MODERATOR).antMatchers("/discuss/delete","/data/**").hasAnyAuthority(AUTHORITY_ADMIN).anyRequest().permitAll().and().csrf().disable();
http://www.ds6.com.cn/news/51185.html

相关文章:

  • 网站挂标 怎么做外包公司是什么意思
  • 网站开发用什么技术asp营销推广活动策划
  • 嘉兴网站建设公司百度推广管理
  • 可以做代发货源的网站信息流广告代运营
  • 衡水手机网站建设上海网站制作开发
  • 用 net做网站网站广告收费标准
  • 做网站架构图aso优化贴吧
  • 北京网站手机站建设公司电话号码成都关键词优化平台
  • 用flask做的网站有哪些网站优化排名易下拉稳定
  • 兰州北京网站建设一站式媒体发稿平台
  • 西宁网站建设制作公司域名收录查询
  • 网站设计语言翻译如何推广普通话的建议6条
  • 网站点击量怎么看潍坊网站seo
  • 网站logo怎么做的武汉seo学徒
  • 什么行业必须做网站成都疫情最新情况
  • 如何制作一个优秀网站建设做一个自己的网站
  • 网站建设套餐内容国际新闻视频
  • 医疗行业网站怎么做服务外包公司
  • 自己电脑做网站服务器苏州百度快速排名优化
  • 西部数据网站助手seo推广优化平台
  • 莆田社交网站网址提交
  • 青岛网站权重提升白酒最有效的推广方式
  • 宁波企业免费建站顶尖文案网站
  • 营销网站和展示型网站重庆搜索排名提升
  • 中国保密在线网站培训系统seo搜索引擎优化方案
  • 中国人做外贸生意的网站深圳最好的外贸seo培训
  • 网页 网 址网站区别北京seo公司华网白帽
  • 长春电商网站建设哪家专业免费搭建网站的软件
  • 东莞沙田门户网站建设小说百度搜索风云榜
  • 网站文件夹没有权限设置软文广告案例