我在使用Apache Shiro实现SprigBoot WebApp时遇到问题(我在Spring Security中遇到了同样的问题,但我读到Shiro更容易实现 - 对我来说不幸的是不是。)
所以,一开始,我使用springboot和shiro,我的网页使用* .html使用thymeleaf和bootstrap,我使用数据库MySQL使用Hibernate,我不希望静态用户只是来自db,I&# 39;我试图基于一些教程来实现Shiro,但我无法做到。
我的问题到底是什么? - 我无法登录点击登录后没有任何反应,只需" refres"页。
底部充满了我的代码:
pom.xml依赖关系
r = requests.post('http://localhost:8000/python-data', json = data)
MainStConfig.java配置
<dependencies>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-web</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>3.3.7</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>2.1.4</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>webjars-locator</artifactId>
<version>0.32</version>
</dependency>
</dependencies>
MainStApplication.java启动应用
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = {"app.controllers", "app.service"})
public class MainStConfig extends WebMvcConfigurerAdapter {
private static final String[] CLASSPATH_RESOURCE_LOCATIONS = {
"classpath:/META-INF/resources/",
"classpath:/resources/",
"classpath:/static/",
"classpath:/public/",
"classpath:/webjars/"
};
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**").addResourceLocations(CLASSPATH_RESOURCE_LOCATIONS);
}
@Bean
public DispatcherServlet dispatcherServlet() {
DispatcherServlet servlet = new DispatcherServlet();
servlet.setDispatchOptionsRequest(true);
return servlet;
}
@Bean
public ServletRegistrationBean dispatcherRegistration(DispatcherServlet dispatcherServlet) {
ServletRegistrationBean registration = new ServletRegistrationBean(dispatcherServlet);
registration.addUrlMappings("/*");
return registration;
}
@Bean(name = "shiroFilter")
public ShiroFilterFactoryBean shiroFilter() {
ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();
shiroFilter.setLoginUrl("/login.html");
shiroFilter.setSuccessUrl("/index.html");
shiroFilter.setUnauthorizedUrl("/index.html?error");
Map<String, String> filterChain = new HashMap<>();
filterChain.put("/", "anon");
filterChain.put("/login", "authc,roles[guest]");
filterChain.put("/admin/**", "authc,roles[ADMIN]");
filterChain.put("/student/**", "authc,roles[STUDENT]");
filterChain.put("/teacher/**", "roles,roles[TEACHER]");
shiroFilter.setFilterChainDefinitionMap(filterChain);
shiroFilter.setSecurityManager(securityManager());
Map<String, Filter> filters = new HashMap<>();
filters.put("anon", new AnonymousFilter());
filters.put("authc", new FormAuthenticationFilter());
filters.put("logout", new LogoutFilter());
filters.put("roles", new RolesAuthorizationFilter());
filters.put("user", new UserFilter());
shiroFilter.setFilters(filters);
return shiroFilter;
}
@Bean
public org.apache.shiro.mgt.SecurityManager securityManager() {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(userRealm());
return securityManager;
}
@Bean(name = "userRealm")
@DependsOn("lifecycleBeanPostProcessor")
public UserRealm userRealm() {
return new UserRealm();
}
@Bean
public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
return new LifecycleBeanPostProcessor();
}
}
MainStInitializer.java
@SpringBootApplication
public class MainStApplication {
public static void main(String[] args) {
SpringApplication.run(MainStApplication.class, args);
}
}
UserRealm.java
public class MainStInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { MainStConfig.class };
}
@Override
protected Class<?>[] getServletConfigClasses() {
return null;
}
@Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
}
LoginController
public class UserRealm extends AuthorizingRealm {
@Autowired
private UserManager userManager;
public UserRealm() {
setName("userRealm");
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
UsernamePasswordToken upat = (UsernamePasswordToken) token;
User user = userManager.getByUsername(upat.getUsername());
if (user != null && user.getPassword().equals(new String(upat.getPassword()))) {
return new SimpleAuthenticationInfo(user, user.getPassword(), getName());
} else {
throw new AuthenticationException("Invalid username/password combination!");
}
}
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
User user = (User)principals.getPrimaryPrincipal();
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
info.addRole(user.getType().toString());
info.addStringPermission(user.getType().toString());
return info;
}
}
IndexController.java
@Controller
public class LoginController {
@ModelAttribute("userR")
public User getUser() {
return new User();
}
@RequestMapping(value = "/login", method = RequestMethod.GET)
public String login() {
return "login";
}
@RequestMapping(value = "/admin/index", method = RequestMethod.GET)
public String admin() {
return "admin/index";
}
@RequestMapping(value = "/student/index", method = RequestMethod.GET)
public String student() {
return "student/index";
}
@RequestMapping(value = "/teacher/index", method = RequestMethod.GET)
public String teacher() {
return "teacher/index";
}
@RequestMapping(value = "/login", method = RequestMethod.POST)
public String login(String username, String password) {
Subject currentUser = SecurityUtils.getSubject();
if (StringUtils.hasText(username) && StringUtils.hasText(password)) {
try {
currentUser.login(new UsernamePasswordToken(username, password));
} catch (Exception e) {
return "login";
}
return "redirect:index";
} else {
return "login";
}
}
/*@RequestMapping(value = "/login", method=RequestMethod.POST)
public String login(Model model, @ModelAttribute("userR") User user, RedirectAttributes redirectAttrs) {
model.addAttribute("login", user.getLogin());
if(user.getLogin().equals("a")) {
return "redirect:/admin/index";
}
if(user.getLogin().equals("s")) {
return "redirect:/student/index";
}
if(user.getLogin().equals("t")) {
return "redirect:/teacher/index";
}
return "index";
}*/
}
UserManager 此类使用dao和其他项目中的User类添加到构建路径。为清楚起见 - 将来的UserHash将是散列密码,实际上db中的密码没有散列(UserHash表中的hash_hash列),底部示例
@Controller
@RequestMapping("/")
public class IndexController {
@RequestMapping({"/", "/index"})
String index() {
return "index";
}
@RequestMapping("/login")
String login() {
return "login";
}
}
我的数据库的屏幕: Screen of 2 tables in DB: User and UserHash
有人可以帮我配置Shiro,我可以使用DB中的数据正确登录吗?
更新1。 这是我的login.html页面
@Controller
public class UserManager {
private UserDao dao = new UserDao();
public UserManager() {
}
public model.user.User getByUsername(String name) {
model.entity.User u = this.dao.findByLogin(name);
model.entity.UserHash h = this.dao.findPassByLogin(name);
return new model.user.User(u).build(h);
}
}
从我的观察中,问题出现在MainStConfig类中,恰好在shiro chain的代码片段中:
<body>
<div id="bodyContainer">
<div id="header"></div>
<div id="body">
<div class="loginPanel panel-default center-block">
<div class="panel-body">
<div>
<p th:if="${loginError}" class="error">Wrong user or password</p>
<form th:action="@{login}" th:object="${userR}" method="post">
<center><h1>Panel logowania</h1></center>
<div class="loginPanelInputFields">
<span class="input-group-addon" id="sizing-addon1">Login</span>
<input type="text" th:field="*{login}" id="username"
name="username" class="form-control" placeholder="login..."
aria-describedby="sizing-addon1" />
</div>
<br />
<div class="loginPanelInputFields">
<span class="input-group-addon" id="sizing-addon1">Haslo</span>
<input type="password" th:field="*{password}" id="password"
name="password" class="form-control" placeholder="haslo..."
aria-describedby="sizing-addon1" />
</div>
<br />
<br />
<input type="submit" class="btn btn-info text-center center-block" value="Zaloguj" />
</form>
</div>
</div>
</div>
</div>
<div id="footer"></div>
</div>
</body>
我错了什么?总是 - 无论我使用db中的正确或错误数据 - 我再次重定向到login.html。 在这种情况下使用方法login()方法= RequestMethod.GET NOT Post ....
我没有错误。我只是无法登录,在写完用户名,密码后点击登录我的页面刷新本身,在LoginController中你可以看到未检查的方法登录我检查的东西,例如如果Username =&#34; a&#34;然后将我重定向到/admin/index.html - 这很有效。
我查了一些东西,当我去/login.html并尝试记录执行后是方法
Map<String, String> filterChain = new HashMap<>();
filterChain.put("/", "anon");
filterChain.put("/login", "authc,roles[guest]");
filterChain.put("/admin/**", "authc,roles[ADMIN]");
filterChain.put("/student/**", "authc,roles[STUDENT]");
filterChain.put("/teacher/**", "roles,roles[TEACHER]");
不是
@RequestMapping(value = "/login", method = RequestMethod.GET)
public String login() {"
我无法理解为什么?