diff --git a/apache-shiro/pom.xml b/apache-shiro/pom.xml index 3df6283437..59bb91d400 100644 --- a/apache-shiro/pom.xml +++ b/apache-shiro/pom.xml @@ -39,10 +39,19 @@ jcl-over-slf4j runtime + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-security + - 1.4.0 + 1.5.3 1.2.17 diff --git a/apache-shiro/src/main/java/com/baeldung/comparison/shiro/CustomRealm.java b/apache-shiro/src/main/java/com/baeldung/comparison/shiro/CustomRealm.java new file mode 100644 index 0000000000..d82fb1a5d5 --- /dev/null +++ b/apache-shiro/src/main/java/com/baeldung/comparison/shiro/CustomRealm.java @@ -0,0 +1,96 @@ +package com.baeldung.comparison.shiro; + +import java.sql.Connection; +import java.sql.SQLException; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.apache.shiro.authc.AuthenticationException; +import org.apache.shiro.authc.AuthenticationInfo; +import org.apache.shiro.authc.AuthenticationToken; +import org.apache.shiro.authc.SimpleAuthenticationInfo; +import org.apache.shiro.authc.UnknownAccountException; +import org.apache.shiro.authc.UsernamePasswordToken; +import org.apache.shiro.authz.AuthorizationInfo; +import org.apache.shiro.authz.SimpleAuthorizationInfo; +import org.apache.shiro.realm.jdbc.JdbcRealm; +import org.apache.shiro.subject.PrincipalCollection; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class CustomRealm extends JdbcRealm { + + private Logger logger = LoggerFactory.getLogger(CustomRealm.class); + + private Map credentials = new HashMap<>(); + private Map> roles = new HashMap<>(); + private Map> permissions = new HashMap<>(); + + { + credentials.put("Tom", "password"); + credentials.put("Jerry", "password"); + + roles.put("Jerry", new HashSet<>(Arrays.asList("ADMIN"))); + roles.put("Tom", new HashSet<>(Arrays.asList("USER"))); + + permissions.put("ADMIN", new HashSet<>(Arrays.asList("READ", "WRITE"))); + permissions.put("USER", new HashSet<>(Arrays.asList("READ"))); + } + + @Override + protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { + + UsernamePasswordToken userToken = (UsernamePasswordToken) token; + + if (userToken.getUsername() == null || userToken.getUsername() + .isEmpty() || !credentials.containsKey(userToken.getUsername())) { + throw new UnknownAccountException("User doesn't exist"); + } + + return new SimpleAuthenticationInfo(userToken.getUsername(), credentials.get(userToken.getUsername()), getName()); + } + + @Override + protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { + Set roles = new HashSet<>(); + Set permissions = new HashSet<>(); + + for (Object user : principals) { + try { + roles.addAll(getRoleNamesForUser(null, (String) user)); + permissions.addAll(getPermissions(null, null, roles)); + } catch (SQLException e) { + logger.error(e.getMessage()); + } + } + SimpleAuthorizationInfo authInfo = new SimpleAuthorizationInfo(roles); + authInfo.setStringPermissions(permissions); + return authInfo; + } + + @Override + protected Set getRoleNamesForUser(Connection conn, String username) throws SQLException { + if (!roles.containsKey(username)) { + throw new SQLException("User doesn't exist"); + } + return roles.get(username); + } + + @Override + protected Set getPermissions(Connection conn, String username, Collection roles) throws SQLException { + Set userPermissions = new HashSet<>(); + + for (String role : roles) { + if (!permissions.containsKey(role)) { + throw new SQLException("Role doesn't exist"); + } + userPermissions.addAll(permissions.get(role)); + } + return userPermissions; + } + +} diff --git a/apache-shiro/src/main/java/com/baeldung/comparison/shiro/ShiroApplication.java b/apache-shiro/src/main/java/com/baeldung/comparison/shiro/ShiroApplication.java new file mode 100644 index 0000000000..92d43ea957 --- /dev/null +++ b/apache-shiro/src/main/java/com/baeldung/comparison/shiro/ShiroApplication.java @@ -0,0 +1,33 @@ +package com.baeldung.comparison.shiro; + +import org.apache.shiro.realm.Realm; +import org.apache.shiro.spring.web.config.DefaultShiroFilterChainDefinition; +import org.apache.shiro.spring.web.config.ShiroFilterChainDefinition; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; +import org.springframework.context.annotation.Bean; + +@SpringBootApplication(exclude = SecurityAutoConfiguration.class) +public class ShiroApplication { + + public static void main(String... args) { + SpringApplication.run(ShiroApplication.class, args); + } + + @Bean + public Realm customRealm() { + return new CustomRealm(); + } + + @Bean + public ShiroFilterChainDefinition shiroFilterChainDefinition() { + DefaultShiroFilterChainDefinition filter = new DefaultShiroFilterChainDefinition(); + + filter.addPathDefinition("/home", "authc"); + filter.addPathDefinition("/**", "anon"); + + return filter; + } + +} diff --git a/apache-shiro/src/main/java/com/baeldung/comparison/shiro/controllers/ShiroController.java b/apache-shiro/src/main/java/com/baeldung/comparison/shiro/controllers/ShiroController.java new file mode 100644 index 0000000000..b819286c57 --- /dev/null +++ b/apache-shiro/src/main/java/com/baeldung/comparison/shiro/controllers/ShiroController.java @@ -0,0 +1,99 @@ +package com.baeldung.comparison.shiro.controllers; + +import javax.servlet.http.HttpServletRequest; + +import org.apache.shiro.SecurityUtils; +import org.apache.shiro.authc.AuthenticationException; +import org.apache.shiro.authc.UsernamePasswordToken; +import org.apache.shiro.subject.Subject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.servlet.mvc.support.RedirectAttributes; + +import com.baeldung.comparison.shiro.models.UserCredentials; + +@Controller +public class ShiroController { + + private Logger logger = LoggerFactory.getLogger(ShiroController.class); + + @GetMapping("/") + public String getIndex() { + return "comparison/index"; + } + + @GetMapping("/login") + public String showLoginPage() { + return "comparison/login"; + } + + @PostMapping("/login") + public String doLogin(HttpServletRequest req, UserCredentials credentials, RedirectAttributes attr) { + + Subject subject = SecurityUtils.getSubject(); + + if (!subject.isAuthenticated()) { + UsernamePasswordToken token = new UsernamePasswordToken(credentials.getUsername(), credentials.getPassword()); + try { + subject.login(token); + } catch (AuthenticationException ae) { + logger.error(ae.getMessage()); + attr.addFlashAttribute("error", "Invalid Credentials"); + return "redirect:/login"; + } + } + return "redirect:/home"; + } + + @GetMapping("/home") + public String getMeHome(Model model) { + + addUserAttributes(model); + + return "comparison/home"; + } + + @GetMapping("/admin") + public String adminOnly(Model model) { + addUserAttributes(model); + + Subject currentUser = SecurityUtils.getSubject(); + if (currentUser.hasRole("ADMIN")) { + model.addAttribute("adminContent", "only admin can view this"); + } + return "comparison/home"; + } + + @PostMapping("/logout") + public String logout() { + Subject subject = SecurityUtils.getSubject(); + subject.logout(); + return "redirect:/"; + } + + private void addUserAttributes(Model model) { + Subject currentUser = SecurityUtils.getSubject(); + String permission = ""; + + if (currentUser.hasRole("ADMIN")) { + model.addAttribute("role", "ADMIN"); + } else if (currentUser.hasRole("USER")) { + model.addAttribute("role", "USER"); + } + + if (currentUser.isPermitted("READ")) { + permission = permission + " READ"; + } + + if (currentUser.isPermitted("WRITE")) { + permission = permission + " WRITE"; + } + model.addAttribute("username", currentUser.getPrincipal()); + model.addAttribute("permission", permission); + } + +} diff --git a/apache-shiro/src/main/java/com/baeldung/comparison/shiro/models/UserCredentials.java b/apache-shiro/src/main/java/com/baeldung/comparison/shiro/models/UserCredentials.java new file mode 100644 index 0000000000..100809f6ea --- /dev/null +++ b/apache-shiro/src/main/java/com/baeldung/comparison/shiro/models/UserCredentials.java @@ -0,0 +1,28 @@ +package com.baeldung.comparison.shiro.models; + +public class UserCredentials { + + private String username; + private String password; + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + @Override + public String toString() { + return "username = " + getUsername(); + } +} diff --git a/apache-shiro/src/main/java/com/baeldung/comparison/springsecurity/Application.java b/apache-shiro/src/main/java/com/baeldung/comparison/springsecurity/Application.java new file mode 100644 index 0000000000..6878c309df --- /dev/null +++ b/apache-shiro/src/main/java/com/baeldung/comparison/springsecurity/Application.java @@ -0,0 +1,19 @@ +package com.baeldung.comparison.springsecurity; + +import org.apache.shiro.spring.boot.autoconfigure.ShiroAnnotationProcessorAutoConfiguration; +import org.apache.shiro.spring.boot.autoconfigure.ShiroAutoConfiguration; +import org.apache.shiro.spring.config.web.autoconfigure.ShiroWebAutoConfiguration; +import org.apache.shiro.spring.config.web.autoconfigure.ShiroWebFilterConfiguration; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication(exclude = {ShiroAutoConfiguration.class, + ShiroAnnotationProcessorAutoConfiguration.class, + ShiroWebAutoConfiguration.class, + ShiroWebFilterConfiguration.class}) +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } +} \ No newline at end of file diff --git a/apache-shiro/src/main/java/com/baeldung/comparison/springsecurity/config/SecurityConfig.java b/apache-shiro/src/main/java/com/baeldung/comparison/springsecurity/config/SecurityConfig.java new file mode 100644 index 0000000000..d838eef9b3 --- /dev/null +++ b/apache-shiro/src/main/java/com/baeldung/comparison/springsecurity/config/SecurityConfig.java @@ -0,0 +1,45 @@ +package com.baeldung.comparison.springsecurity.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; + +@EnableWebSecurity +public class SecurityConfig extends WebSecurityConfigurerAdapter { + + @Override + protected void configure(HttpSecurity http) throws Exception { + http.csrf().disable().authorizeRequests(authorize -> authorize.antMatchers("/index", "/login") + .permitAll() + .antMatchers("/home", "/logout") + .authenticated() + .antMatchers("/admin/**") + .hasRole("ADMIN")) + .formLogin(formLogin -> formLogin.loginPage("/login") + .failureUrl("/login-error")); + } + + @Override + protected void configure(AuthenticationManagerBuilder auth) throws Exception { + auth.inMemoryAuthentication() + .withUser("Jerry") + .password(passwordEncoder().encode("password")) + .authorities("READ", "WRITE") + .roles("ADMIN") + .and() + .withUser("Tom") + .password(passwordEncoder().encode("password")) + .authorities("READ") + .roles("USER"); + } + + @Bean + public PasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(); + } + +} diff --git a/apache-shiro/src/main/java/com/baeldung/comparison/springsecurity/web/SpringController.java b/apache-shiro/src/main/java/com/baeldung/comparison/springsecurity/web/SpringController.java new file mode 100644 index 0000000000..34b6b0c0e3 --- /dev/null +++ b/apache-shiro/src/main/java/com/baeldung/comparison/springsecurity/web/SpringController.java @@ -0,0 +1,79 @@ +package com.baeldung.comparison.springsecurity.web; + +import java.util.Collection; + +import javax.servlet.http.HttpServletRequest; + +import org.springframework.security.authentication.AnonymousAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.User; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; + +@Controller +public class SpringController { + + @GetMapping("/") + public String getIndex() { + return "comparison/index"; + } + + @GetMapping("/login") + public String showLoginPage() { + return "comparison/login"; + } + + @RequestMapping("/login-error") + public String loginError(Model model) { + model.addAttribute("error", "Invalid Credentials"); + return "comparison/login"; + } + + @PostMapping("/login") + public String doLogin(HttpServletRequest req) { + return "redirect:/home"; + } + + @GetMapping("/home") + public String showHomePage(HttpServletRequest req, Model model) { + addUserAttributes(model); + return "comparison/home"; + } + + @GetMapping("/admin") + public String adminOnly(HttpServletRequest req, Model model) { + addUserAttributes(model); + model.addAttribute("adminContent", "only admin can view this"); + return "comparison/home"; + } + + private void addUserAttributes(Model model) { + Authentication auth = SecurityContextHolder.getContext() + .getAuthentication(); + if (auth != null && !auth.getClass() + .equals(AnonymousAuthenticationToken.class)) { + User user = (User) auth.getPrincipal(); + model.addAttribute("username", user.getUsername()); + + Collection authorities = user.getAuthorities(); + + for (GrantedAuthority authority : authorities) { + if (authority.getAuthority() + .contains("USER")) { + model.addAttribute("role", "USER"); + model.addAttribute("permission", "READ"); + } else if (authority.getAuthority() + .contains("ADMIN")) { + model.addAttribute("role", "ADMIN"); + model.addAttribute("permission", "READ WRITE"); + } + } + } + } + +} diff --git a/apache-shiro/src/main/java/com/baeldung/Main.java b/apache-shiro/src/main/java/com/baeldung/intro/Main.java similarity index 99% rename from apache-shiro/src/main/java/com/baeldung/Main.java rename to apache-shiro/src/main/java/com/baeldung/intro/Main.java index 99515bb705..fbd3bc7ac7 100644 --- a/apache-shiro/src/main/java/com/baeldung/Main.java +++ b/apache-shiro/src/main/java/com/baeldung/intro/Main.java @@ -1,4 +1,4 @@ -package com.baeldung; +package com.baeldung.intro; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.AuthenticationException; diff --git a/apache-shiro/src/main/java/com/baeldung/MyCustomRealm.java b/apache-shiro/src/main/java/com/baeldung/intro/MyCustomRealm.java similarity index 99% rename from apache-shiro/src/main/java/com/baeldung/MyCustomRealm.java rename to apache-shiro/src/main/java/com/baeldung/intro/MyCustomRealm.java index 6d7c01d96e..9d65e37ec4 100644 --- a/apache-shiro/src/main/java/com/baeldung/MyCustomRealm.java +++ b/apache-shiro/src/main/java/com/baeldung/intro/MyCustomRealm.java @@ -1,4 +1,4 @@ -package com.baeldung; +package com.baeldung.intro; import java.sql.Connection; import java.sql.SQLException; diff --git a/apache-shiro/src/main/java/com/baeldung/ShiroSpringApplication.java b/apache-shiro/src/main/java/com/baeldung/intro/ShiroSpringApplication.java similarity index 80% rename from apache-shiro/src/main/java/com/baeldung/ShiroSpringApplication.java rename to apache-shiro/src/main/java/com/baeldung/intro/ShiroSpringApplication.java index e12d3ebffa..dc288a273b 100644 --- a/apache-shiro/src/main/java/com/baeldung/ShiroSpringApplication.java +++ b/apache-shiro/src/main/java/com/baeldung/intro/ShiroSpringApplication.java @@ -1,4 +1,4 @@ -package com.baeldung; +package com.baeldung.intro; import org.apache.shiro.realm.Realm; import org.apache.shiro.spring.web.config.DefaultShiroFilterChainDefinition; @@ -7,12 +7,13 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; import org.springframework.context.annotation.Bean; /** * Created by smatt on 21/08/2017. */ -@SpringBootApplication +@SpringBootApplication(exclude = SecurityAutoConfiguration.class) public class ShiroSpringApplication { private static final transient Logger log = LoggerFactory.getLogger(ShiroSpringApplication.class); @@ -29,7 +30,7 @@ public class ShiroSpringApplication { @Bean - public ShiroFilterChainDefinition shiroFilterChainDefinition() { + public ShiroFilterChainDefinition filterChainDefinition() { DefaultShiroFilterChainDefinition filter = new DefaultShiroFilterChainDefinition(); diff --git a/apache-shiro/src/main/java/com/baeldung/controllers/ShiroSpringController.java b/apache-shiro/src/main/java/com/baeldung/intro/controllers/ShiroSpringController.java similarity index 97% rename from apache-shiro/src/main/java/com/baeldung/controllers/ShiroSpringController.java rename to apache-shiro/src/main/java/com/baeldung/intro/controllers/ShiroSpringController.java index 2713786d71..1605f390a8 100644 --- a/apache-shiro/src/main/java/com/baeldung/controllers/ShiroSpringController.java +++ b/apache-shiro/src/main/java/com/baeldung/intro/controllers/ShiroSpringController.java @@ -1,6 +1,5 @@ -package com.baeldung.controllers; +package com.baeldung.intro.controllers; -import com.baeldung.models.UserCredentials; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.UsernamePasswordToken; @@ -13,6 +12,8 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.servlet.mvc.support.RedirectAttributes; +import com.baeldung.intro.models.UserCredentials; + import javax.servlet.http.HttpServletRequest; @Controller diff --git a/apache-shiro/src/main/java/com/baeldung/models/UserCredentials.java b/apache-shiro/src/main/java/com/baeldung/intro/models/UserCredentials.java similarity index 95% rename from apache-shiro/src/main/java/com/baeldung/models/UserCredentials.java rename to apache-shiro/src/main/java/com/baeldung/intro/models/UserCredentials.java index 51b429046a..6614d07257 100644 --- a/apache-shiro/src/main/java/com/baeldung/models/UserCredentials.java +++ b/apache-shiro/src/main/java/com/baeldung/intro/models/UserCredentials.java @@ -1,4 +1,4 @@ -package com.baeldung.models; +package com.baeldung.intro.models; public class UserCredentials { diff --git a/apache-shiro/src/main/java/com/baeldung/shiro/permissions/custom/Main.java b/apache-shiro/src/main/java/com/baeldung/permissions/custom/Main.java similarity index 98% rename from apache-shiro/src/main/java/com/baeldung/shiro/permissions/custom/Main.java rename to apache-shiro/src/main/java/com/baeldung/permissions/custom/Main.java index a902a24388..c9ab2b6e37 100644 --- a/apache-shiro/src/main/java/com/baeldung/shiro/permissions/custom/Main.java +++ b/apache-shiro/src/main/java/com/baeldung/permissions/custom/Main.java @@ -1,4 +1,4 @@ -package com.baeldung.shiro.permissions.custom; +package com.baeldung.permissions.custom; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.AuthenticationException; diff --git a/apache-shiro/src/main/java/com/baeldung/shiro/permissions/custom/PathPermission.java b/apache-shiro/src/main/java/com/baeldung/permissions/custom/PathPermission.java similarity index 90% rename from apache-shiro/src/main/java/com/baeldung/shiro/permissions/custom/PathPermission.java rename to apache-shiro/src/main/java/com/baeldung/permissions/custom/PathPermission.java index f7dfbda06a..828484087f 100644 --- a/apache-shiro/src/main/java/com/baeldung/shiro/permissions/custom/PathPermission.java +++ b/apache-shiro/src/main/java/com/baeldung/permissions/custom/PathPermission.java @@ -1,4 +1,4 @@ -package com.baeldung.shiro.permissions.custom; +package com.baeldung.permissions.custom; import org.apache.shiro.authz.Permission; diff --git a/apache-shiro/src/main/java/com/baeldung/shiro/permissions/custom/PathPermissionResolver.java b/apache-shiro/src/main/java/com/baeldung/permissions/custom/PathPermissionResolver.java similarity index 88% rename from apache-shiro/src/main/java/com/baeldung/shiro/permissions/custom/PathPermissionResolver.java rename to apache-shiro/src/main/java/com/baeldung/permissions/custom/PathPermissionResolver.java index 4b60d2fbd4..30bdece65f 100644 --- a/apache-shiro/src/main/java/com/baeldung/shiro/permissions/custom/PathPermissionResolver.java +++ b/apache-shiro/src/main/java/com/baeldung/permissions/custom/PathPermissionResolver.java @@ -1,4 +1,4 @@ -package com.baeldung.shiro.permissions.custom; +package com.baeldung.permissions.custom; import org.apache.shiro.authz.Permission; import org.apache.shiro.authz.permission.PermissionResolver; diff --git a/apache-shiro/src/main/resources/templates/comparison/home.ftl b/apache-shiro/src/main/resources/templates/comparison/home.ftl new file mode 100644 index 0000000000..37eb3d1812 --- /dev/null +++ b/apache-shiro/src/main/resources/templates/comparison/home.ftl @@ -0,0 +1,19 @@ + + + Home Page + + +

Welcome ${username}!

+

Role: ${role}

+

Permissions

+

${permission}

+Admin only +<#if adminContent??> + ${adminContent} + +
+
+ +
+ + \ No newline at end of file diff --git a/apache-shiro/src/main/resources/templates/comparison/index.ftl b/apache-shiro/src/main/resources/templates/comparison/index.ftl new file mode 100644 index 0000000000..8f35c0af1b --- /dev/null +++ b/apache-shiro/src/main/resources/templates/comparison/index.ftl @@ -0,0 +1,10 @@ + + + Index + + +

Welcome Guest!

+
+ Go to the secured page + + \ No newline at end of file diff --git a/apache-shiro/src/main/resources/templates/comparison/login.ftl b/apache-shiro/src/main/resources/templates/comparison/login.ftl new file mode 100644 index 0000000000..7340f47204 --- /dev/null +++ b/apache-shiro/src/main/resources/templates/comparison/login.ftl @@ -0,0 +1,25 @@ + + + Login + + +

Login

+
+
+ <#if (error?length > 0)??> +

${error}

+ <#else> + + + +
+ +

+ +
+ +

+ +
+ + \ No newline at end of file diff --git a/apache-shiro/src/test/java/com/baeldung/comparison/shiro/SpringContextTest.java b/apache-shiro/src/test/java/com/baeldung/comparison/shiro/SpringContextTest.java new file mode 100644 index 0000000000..0d150d0fad --- /dev/null +++ b/apache-shiro/src/test/java/com/baeldung/comparison/shiro/SpringContextTest.java @@ -0,0 +1,20 @@ +package com.baeldung.comparison.shiro; + + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import com.baeldung.comparison.shiro.ShiroApplication; + +@ExtendWith(SpringExtension.class) +@SpringBootTest(classes = { ShiroApplication.class }) +public class SpringContextTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + + } + +} \ No newline at end of file diff --git a/apache-shiro/src/test/java/com/baeldung/comparison/springsecurity/SpringContextTest.java b/apache-shiro/src/test/java/com/baeldung/comparison/springsecurity/SpringContextTest.java new file mode 100644 index 0000000000..5044b40e31 --- /dev/null +++ b/apache-shiro/src/test/java/com/baeldung/comparison/springsecurity/SpringContextTest.java @@ -0,0 +1,19 @@ +package com.baeldung.comparison.springsecurity; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import com.baeldung.comparison.springsecurity.Application; + +@ExtendWith(SpringExtension.class) +@SpringBootTest(classes = { Application.class }) +public class SpringContextTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + + } + +} \ No newline at end of file