Skip to content

Commit f57f769

Browse files
authored
Merge pull request eugenp#62 from eugenp/master
update
2 parents fcd60b6 + 301ec10 commit f57f769

File tree

210 files changed

+3618
-449
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

210 files changed

+3618
-449
lines changed

apache-shiro/pom.xml

+10-1
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,19 @@
3939
<artifactId>jcl-over-slf4j</artifactId>
4040
<scope>runtime</scope>
4141
</dependency>
42+
<!-- spring-sec -->
43+
<dependency>
44+
<groupId>org.springframework.boot</groupId>
45+
<artifactId>spring-boot-starter-web</artifactId>
46+
</dependency>
47+
<dependency>
48+
<groupId>org.springframework.boot</groupId>
49+
<artifactId>spring-boot-starter-security</artifactId>
50+
</dependency>
4251
</dependencies>
4352

4453
<properties>
45-
<apache-shiro-core-version>1.4.0</apache-shiro-core-version>
54+
<apache-shiro-core-version>1.5.3</apache-shiro-core-version>
4655
<log4j-version>1.2.17</log4j-version>
4756
</properties>
4857

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
package com.baeldung.comparison.shiro;
2+
3+
import java.sql.Connection;
4+
import java.sql.SQLException;
5+
import java.util.Arrays;
6+
import java.util.Collection;
7+
import java.util.HashMap;
8+
import java.util.HashSet;
9+
import java.util.Map;
10+
import java.util.Set;
11+
12+
import org.apache.shiro.authc.AuthenticationException;
13+
import org.apache.shiro.authc.AuthenticationInfo;
14+
import org.apache.shiro.authc.AuthenticationToken;
15+
import org.apache.shiro.authc.SimpleAuthenticationInfo;
16+
import org.apache.shiro.authc.UnknownAccountException;
17+
import org.apache.shiro.authc.UsernamePasswordToken;
18+
import org.apache.shiro.authz.AuthorizationInfo;
19+
import org.apache.shiro.authz.SimpleAuthorizationInfo;
20+
import org.apache.shiro.realm.jdbc.JdbcRealm;
21+
import org.apache.shiro.subject.PrincipalCollection;
22+
import org.slf4j.Logger;
23+
import org.slf4j.LoggerFactory;
24+
25+
public class CustomRealm extends JdbcRealm {
26+
27+
private Logger logger = LoggerFactory.getLogger(CustomRealm.class);
28+
29+
private Map<String, String> credentials = new HashMap<>();
30+
private Map<String, Set<String>> roles = new HashMap<>();
31+
private Map<String, Set<String>> permissions = new HashMap<>();
32+
33+
{
34+
credentials.put("Tom", "password");
35+
credentials.put("Jerry", "password");
36+
37+
roles.put("Jerry", new HashSet<>(Arrays.asList("ADMIN")));
38+
roles.put("Tom", new HashSet<>(Arrays.asList("USER")));
39+
40+
permissions.put("ADMIN", new HashSet<>(Arrays.asList("READ", "WRITE")));
41+
permissions.put("USER", new HashSet<>(Arrays.asList("READ")));
42+
}
43+
44+
@Override
45+
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
46+
47+
UsernamePasswordToken userToken = (UsernamePasswordToken) token;
48+
49+
if (userToken.getUsername() == null || userToken.getUsername()
50+
.isEmpty() || !credentials.containsKey(userToken.getUsername())) {
51+
throw new UnknownAccountException("User doesn't exist");
52+
}
53+
54+
return new SimpleAuthenticationInfo(userToken.getUsername(), credentials.get(userToken.getUsername()), getName());
55+
}
56+
57+
@Override
58+
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
59+
Set<String> roles = new HashSet<>();
60+
Set<String> permissions = new HashSet<>();
61+
62+
for (Object user : principals) {
63+
try {
64+
roles.addAll(getRoleNamesForUser(null, (String) user));
65+
permissions.addAll(getPermissions(null, null, roles));
66+
} catch (SQLException e) {
67+
logger.error(e.getMessage());
68+
}
69+
}
70+
SimpleAuthorizationInfo authInfo = new SimpleAuthorizationInfo(roles);
71+
authInfo.setStringPermissions(permissions);
72+
return authInfo;
73+
}
74+
75+
@Override
76+
protected Set<String> getRoleNamesForUser(Connection conn, String username) throws SQLException {
77+
if (!roles.containsKey(username)) {
78+
throw new SQLException("User doesn't exist");
79+
}
80+
return roles.get(username);
81+
}
82+
83+
@Override
84+
protected Set<String> getPermissions(Connection conn, String username, Collection<String> roles) throws SQLException {
85+
Set<String> userPermissions = new HashSet<>();
86+
87+
for (String role : roles) {
88+
if (!permissions.containsKey(role)) {
89+
throw new SQLException("Role doesn't exist");
90+
}
91+
userPermissions.addAll(permissions.get(role));
92+
}
93+
return userPermissions;
94+
}
95+
96+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package com.baeldung.comparison.shiro;
2+
3+
import org.apache.shiro.realm.Realm;
4+
import org.apache.shiro.spring.web.config.DefaultShiroFilterChainDefinition;
5+
import org.apache.shiro.spring.web.config.ShiroFilterChainDefinition;
6+
import org.springframework.boot.SpringApplication;
7+
import org.springframework.boot.autoconfigure.SpringBootApplication;
8+
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
9+
import org.springframework.context.annotation.Bean;
10+
11+
@SpringBootApplication(exclude = SecurityAutoConfiguration.class)
12+
public class ShiroApplication {
13+
14+
public static void main(String... args) {
15+
SpringApplication.run(ShiroApplication.class, args);
16+
}
17+
18+
@Bean
19+
public Realm customRealm() {
20+
return new CustomRealm();
21+
}
22+
23+
@Bean
24+
public ShiroFilterChainDefinition shiroFilterChainDefinition() {
25+
DefaultShiroFilterChainDefinition filter = new DefaultShiroFilterChainDefinition();
26+
27+
filter.addPathDefinition("/home", "authc");
28+
filter.addPathDefinition("/**", "anon");
29+
30+
return filter;
31+
}
32+
33+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
package com.baeldung.comparison.shiro.controllers;
2+
3+
import javax.servlet.http.HttpServletRequest;
4+
5+
import org.apache.shiro.SecurityUtils;
6+
import org.apache.shiro.authc.AuthenticationException;
7+
import org.apache.shiro.authc.UsernamePasswordToken;
8+
import org.apache.shiro.subject.Subject;
9+
import org.slf4j.Logger;
10+
import org.slf4j.LoggerFactory;
11+
import org.springframework.stereotype.Controller;
12+
import org.springframework.ui.Model;
13+
import org.springframework.web.bind.annotation.GetMapping;
14+
import org.springframework.web.bind.annotation.PostMapping;
15+
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
16+
17+
import com.baeldung.comparison.shiro.models.UserCredentials;
18+
19+
@Controller
20+
public class ShiroController {
21+
22+
private Logger logger = LoggerFactory.getLogger(ShiroController.class);
23+
24+
@GetMapping("/")
25+
public String getIndex() {
26+
return "comparison/index";
27+
}
28+
29+
@GetMapping("/login")
30+
public String showLoginPage() {
31+
return "comparison/login";
32+
}
33+
34+
@PostMapping("/login")
35+
public String doLogin(HttpServletRequest req, UserCredentials credentials, RedirectAttributes attr) {
36+
37+
Subject subject = SecurityUtils.getSubject();
38+
39+
if (!subject.isAuthenticated()) {
40+
UsernamePasswordToken token = new UsernamePasswordToken(credentials.getUsername(), credentials.getPassword());
41+
try {
42+
subject.login(token);
43+
} catch (AuthenticationException ae) {
44+
logger.error(ae.getMessage());
45+
attr.addFlashAttribute("error", "Invalid Credentials");
46+
return "redirect:/login";
47+
}
48+
}
49+
return "redirect:/home";
50+
}
51+
52+
@GetMapping("/home")
53+
public String getMeHome(Model model) {
54+
55+
addUserAttributes(model);
56+
57+
return "comparison/home";
58+
}
59+
60+
@GetMapping("/admin")
61+
public String adminOnly(Model model) {
62+
addUserAttributes(model);
63+
64+
Subject currentUser = SecurityUtils.getSubject();
65+
if (currentUser.hasRole("ADMIN")) {
66+
model.addAttribute("adminContent", "only admin can view this");
67+
}
68+
return "comparison/home";
69+
}
70+
71+
@PostMapping("/logout")
72+
public String logout() {
73+
Subject subject = SecurityUtils.getSubject();
74+
subject.logout();
75+
return "redirect:/";
76+
}
77+
78+
private void addUserAttributes(Model model) {
79+
Subject currentUser = SecurityUtils.getSubject();
80+
String permission = "";
81+
82+
if (currentUser.hasRole("ADMIN")) {
83+
model.addAttribute("role", "ADMIN");
84+
} else if (currentUser.hasRole("USER")) {
85+
model.addAttribute("role", "USER");
86+
}
87+
88+
if (currentUser.isPermitted("READ")) {
89+
permission = permission + " READ";
90+
}
91+
92+
if (currentUser.isPermitted("WRITE")) {
93+
permission = permission + " WRITE";
94+
}
95+
model.addAttribute("username", currentUser.getPrincipal());
96+
model.addAttribute("permission", permission);
97+
}
98+
99+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package com.baeldung.comparison.shiro.models;
2+
3+
public class UserCredentials {
4+
5+
private String username;
6+
private String password;
7+
8+
public String getUsername() {
9+
return username;
10+
}
11+
12+
public void setUsername(String username) {
13+
this.username = username;
14+
}
15+
16+
public String getPassword() {
17+
return password;
18+
}
19+
20+
public void setPassword(String password) {
21+
this.password = password;
22+
}
23+
24+
@Override
25+
public String toString() {
26+
return "username = " + getUsername();
27+
}
28+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package com.baeldung.comparison.springsecurity;
2+
3+
import org.apache.shiro.spring.boot.autoconfigure.ShiroAnnotationProcessorAutoConfiguration;
4+
import org.apache.shiro.spring.boot.autoconfigure.ShiroAutoConfiguration;
5+
import org.apache.shiro.spring.config.web.autoconfigure.ShiroWebAutoConfiguration;
6+
import org.apache.shiro.spring.config.web.autoconfigure.ShiroWebFilterConfiguration;
7+
import org.springframework.boot.SpringApplication;
8+
import org.springframework.boot.autoconfigure.SpringBootApplication;
9+
10+
@SpringBootApplication(exclude = {ShiroAutoConfiguration.class,
11+
ShiroAnnotationProcessorAutoConfiguration.class,
12+
ShiroWebAutoConfiguration.class,
13+
ShiroWebFilterConfiguration.class})
14+
public class Application {
15+
16+
public static void main(String[] args) {
17+
SpringApplication.run(Application.class, args);
18+
}
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package com.baeldung.comparison.springsecurity.config;
2+
3+
import org.springframework.context.annotation.Bean;
4+
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
5+
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
6+
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
7+
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
8+
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
9+
import org.springframework.security.crypto.password.PasswordEncoder;
10+
11+
@EnableWebSecurity
12+
public class SecurityConfig extends WebSecurityConfigurerAdapter {
13+
14+
@Override
15+
protected void configure(HttpSecurity http) throws Exception {
16+
http.csrf().disable().authorizeRequests(authorize -> authorize.antMatchers("/index", "/login")
17+
.permitAll()
18+
.antMatchers("/home", "/logout")
19+
.authenticated()
20+
.antMatchers("/admin/**")
21+
.hasRole("ADMIN"))
22+
.formLogin(formLogin -> formLogin.loginPage("/login")
23+
.failureUrl("/login-error"));
24+
}
25+
26+
@Override
27+
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
28+
auth.inMemoryAuthentication()
29+
.withUser("Jerry")
30+
.password(passwordEncoder().encode("password"))
31+
.authorities("READ", "WRITE")
32+
.roles("ADMIN")
33+
.and()
34+
.withUser("Tom")
35+
.password(passwordEncoder().encode("password"))
36+
.authorities("READ")
37+
.roles("USER");
38+
}
39+
40+
@Bean
41+
public PasswordEncoder passwordEncoder() {
42+
return new BCryptPasswordEncoder();
43+
}
44+
45+
}

0 commit comments

Comments
 (0)