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

承接网站开发 app开发seo搜索引擎实战详解

承接网站开发 app开发,seo搜索引擎实战详解,金坛网站开发,仙居做网站在哪里做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.hkea.cn/news/796684/

相关文章:

  • 安徽省建设业协会网站个人网页制作教程
  • 好的摄影网站推荐福州seo顾问
  • html做的好看的网站如何宣传推广产品
  • 微信手机网站制作怎么引流客源最好的方法
  • 宿州建设网站公司前端seo搜索引擎优化
  • 做王境泽表情的网站百度seo关键词优化排名
  • 怎么选择无锡网站建设虚拟主机搭建网站
  • 做原油期货关注什么网站搜索引擎优化是做什么
  • 微信小程序怎么制作游戏安卓优化清理大师
  • 胶南做网站初学者做电商怎么入手
  • 网站为什么要维护佛山网络营销推广
  • 国企网站建设报告怎么建造自己的网站
  • 免费做司考真题的网站余姚网站如何进行优化
  • 如何网站开发1688网站
  • 丽水专业网站建设价格青岛网站优化
  • 网站开发专业培训学校百度推广登录官网入口
  • 贵阳做网站公司网站热度查询
  • 做课件最好的素材网站考拉seo
  • 网站建设玖首选金手指seo网站优化收藏
  • 台州卓远做网站好不好广州seo教程
  • dz网站数据备份bt磁力猪
  • github 可以做网站吗360seo
  • 杭州 企业门户网站建设爱链
  • dj那个网站做的好长沙公司网络营销推广
  • 设计师培训招生视频黑帽seo联系方式
  • 做网上贸易哪个网站好西宁网站seo
  • 电子烟网站建设杯子软文营销300字
  • 广州企业网站制作怎么做营销推广
  • 网站建设服务器在香港郑州网站建设专业乐云seo
  • 河北建设工程交易信息网海口关键词优化报价