2017 年 5 月 29 日由 Sébastien Blanc 撰写
./standalone.sh(bat)然后打开浏览器,转到 http://127.0.0.1:8080/auth。 由于这是服务器第一次运行,您需要创建一个管理员用户,所以让我们创建一个用户名为 admin,密码为 admin 的管理员用户。
<html> <head> <title>My awesome landing page</title> </head> <body> <h2>Landing page</h2> <a href="/products">My products</a> </body> </html>现在我们需要一个控制器。
@Controller class ProductController { @Autowired ProductService productService; @GetMapping(path = "/products") public String getProducts(Model model){ model.addAttribute("products", productService.getProducts()); return "products"; } @GetMapping(path = "/logout") public String logout(HttpServletRequest request) throws ServletException { request.logout(); return "/"; } }如您所见,它很简单;我们为产品页面定义了一个映射,为注销操作定义了一个映射。您还会注意到,我们正在调用一个“ProductService”,它将返回一个字符串列表,这些字符串将放入我们的 Spring MVC Model 对象中,所以让我们创建该服务。
@Component class ProductService { public List<String> getProducts() { return Arrays.asList("iPad","iPod","iPhone"); } }我们还需要创建 product.ftl 模板,在“src/resources/templates”中创建此文件。
<#import "/spring.ftl" as spring> <html> <h2>My products</h2> <ul> <#list products as product> <li>$amp{product}</li> </#list> </ul> <p> <a href="/logout">Logout</a> </p> </html>在这里,我们只是简单地遍历 Spring MVC Model 对象中的产品列表,并添加一个从应用程序注销的链接。剩下的就是将一些 keycloak 属性添加到我们的 application.properties 中。
keycloak.auth-server-url=http://127.0.0.1:8080/auth keycloak.realm=springboot keycloak.public-client=true keycloak.resource=product-app然后我们需要定义一些安全约束,就像在 web.xml 中使用 Java EE 应用程序一样。
keycloak.security-constraints[0].authRoles[0]=user keycloak.security-constraints[0].securityCollections[0].patterns[0]=/products/*在这里,我们只是简单地定义对 /products/* 的每个请求都应该由经过身份验证的用户执行,并且该用户应该具有“user”角色。最后一个属性是确保我们的应用程序将在端口 8081 上运行。
server.port=8081一切准备就绪,我们可以运行我们的应用程序了!您可以通过多种方式运行您的 Spring Boot 应用程序,使用 Maven,您只需执行
mvn clean spring-boot:run现在浏览到“http://127.0.0.1:8080”,您应该会看到登录页面,点击“产品”链接,您将被重定向到 Keycloak 登录页面。
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency>
@Configuration @EnableWebSecurity @ComponentScan(basePackageClasses = KeycloakSecurityComponents.class) class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter { /** * Registers the KeycloakAuthenticationProvider with the authentication manager. */ @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider(); keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper()); auth.authenticationProvider(keycloakAuthenticationProvider); } @Bean public KeycloakConfigResolver KeycloakConfigResolver() { return new KeycloakSpringBootConfigResolver(); } /** * Defines the session authentication strategy. */ @Bean @Override protected SessionAuthenticationStrategy sessionAuthenticationStrategy() { return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl()); } @Override protected void configure(HttpSecurity http) throws Exception { super.configure(http); http .authorizeRequests() .antMatchers("/products*").hasRole("user") .anyRequest().permitAll(); } }让我们仔细看看最重要的方法。
keycloak.principal-attribute=preferred_username现在,我们甚至可以将 Principal 注入到我们的控制器方法中,并将用户名放入 Spring MVC 模型中。
@GetMapping(path = "/products") public String getProducts(Principal principal, Model model){ model.addAttribute("principal",principal); model.addAttribute("products", productService.getProducts()); return "products"; }最后,我们更新 product.ftl 模板以打印出用户名。
<#import "/spring.ftl" as spring> <html> <h2>Hello $amp{principal.getName()}</h2> <ul> <#list products as product> <li>$amp{product}</li> </#list> </ul> <p> <a href="/logout">Logout</a> </p> </html>重新启动您的应用程序,重新进行身份验证,它应该仍然有效,您还应该能够看到用户名打印在产品页面上。