Multi Client Development with Spring - Josh Long

2,375 views

Published on

No application is an island and this is more obvious today than ever as applications extend their reach into people's pockets, desktops, tablets, TVs, blueray players and cars. What's a modern developer to do to support these many platforms? In this talk, join Josh Long to learn how Spring can extend your reach through (sometimes Spring Security OAuth-secured) RESTful services exposed through Spring MVC, HTML5 and client specific rendering thanks to Spring Mobile, and powerful, native support for Android with Spring Android.

Published in: Technology
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
2,375
On SlideShare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
0
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Multi Client Development with Spring - Josh Long

  1. 1. © 2013 SpringSource, by VMwareMulti Client Development with SpringJosh Long (⻰龙之春)@starbuxmanjoshlong.comjosh.long@springsource.comslideshare.net/joshlongWednesday, June 5, 13
  2. 2. Spring’s Servlet supportWednesday, June 5, 13
  3. 3. Servlet 3.0 Initializer Classespublic class SampleWebApplicationInitializer implements WebApplicationInitializer {public void onStartup(ServletContext sc) throws ServletException {AnnotationConfigWebApplicationContext ac = new AnnotationConfigWebApplicationContext();ac.setServletContext(sc);ac.scan( “a.package.full.of.services”, “a.package.full.of.controllers” );sc.addServlet("spring", new DispatcherServlet(ac));}}Wednesday, June 5, 13
  4. 4. Servlet Support in Spring§ Spring Dispatcher Servlet provides a lot of powerful support§ lots of convenient utility objectsHttpRequestHandlers supports remoting: Caucho, Resin, JAX RPC, etc.DelegatingFilterProxy javax.filter.Filter that delegates to a Spring-managed lifecycleHandlerInterceptor wraps requests to HttpRequestHandlersServletWrappingController lets you force requests to a servlet through the Spring Handler chainOncePerRequestFilter ensures that an action only occurs onceWebApplicationContextUtils has a static method to look up the current ApplicationContext given a ServletContextWednesday, June 5, 13
  5. 5. Spring Web Framework Support•Spring Faces for JSF 1 and 2•Struts support for Struts 1•Tapestry, Struts 2, Stripes, Wicket, Vaadin, Play framework, etc.•GWT, FlexWednesday, June 5, 13
  6. 6. introducing Spring MVCWednesday, June 5, 13
  7. 7. classic Spring MVC application architectureDispatcherServlet controllerviewtemplatedelegaterequestdelegaterendering ofresponserenderresponsereturncontrolmodelmodelincomingrequestsreturnresponseWednesday, June 5, 13
  8. 8. the anatomy of a Spring MVC controller@Controllerpublic class CustomerController {// ...}Wednesday, June 5, 13
  9. 9. the anatomy of a Spring MVC controller@Controllerpublic class CustomerController {@RequestMapping(value= “/url/of/my/resource”)public String processTheRequest() {// ...return “home”;}}GET http://127.0.0.1:8080/url/of/my/resourceWednesday, June 5, 13
  10. 10. the anatomy of a Spring MVC controller@Controllerpublic class CustomerController {@RequestMapping(value= “/url/of/my/resource”, method = RequestMethod.GET)public String processTheRequest() {// ...return “home”;}}GET http://127.0.0.1:8080/url/of/my/resourceWednesday, June 5, 13
  11. 11. the anatomy of a Spring MVC controller@Controllerpublic class CustomerController {@RequestMapping(value=“/url/of/my/resource”, method = RequestMethod.GET)public String processTheRequest( HttpServletRequest request) {String contextPath = request.getContextPath();// ...return “home”;}}GET http://127.0.0.1:8080/url/of/my/resourceWednesday, June 5, 13
  12. 12. the anatomy of a Spring MVC controller@Controllerpublic class CustomerController {@RequestMapping(value=“/url/of/my/resource”, method = RequestMethod.GET)public String processTheRequest( @RequestParam(“search”) String searchQuery){// ...return “home”;}}GET http://127.0.0.1:8080/url/of/my/resource?search=searchQueryWednesday, June 5, 13
  13. 13. the anatomy of a Spring MVC controller@Controllerpublic class CustomerController {@RequestMapping(value=“/url/of/my/{id}”, method = RequestMethod.GET)public String processTheRequest( @PathVariable(“id”) Long id){// ...return “home”;}}GET http://127.0.0.1:8080/url/of/my/12345Wednesday, June 5, 13
  14. 14. the anatomy of a Spring MVC controller@Controllerpublic class CustomerController {@Inject private CustomerService service ;@RequestMapping(value=“/url/of/my/{id}”, method = RequestMethod.GET)public String processTheRequest(Model model, @PathVariable(“id”) Long id){model.addAttribute(“customer”, service.getCustomerById( id ) );return “home”;}}GET http://127.0.0.1:8080/url/of/my/12345Wednesday, June 5, 13
  15. 15. the anatomy of a Spring MVC controller@Controllerpublic class CustomerController {@RequestMapping(value=“/url/of/my/{id}”, method = RequestMethod.GET)public String processTheRequest( ... ){return “home”;}}Wednesday, June 5, 13
  16. 16. the anatomy of a Spring MVC controller@Controllerpublic class CustomerController {@RequestMapping(value=“/url/of/my/{id}”, method = RequestMethod.GET)public View processTheRequest( ... ){return new XsltView(...);}}Wednesday, June 5, 13
  17. 17. the anatomy of a Spring MVC controller@Controllerpublic class CustomerController {@RequestMapping(value=“/url/of/my/{id}”, method = RequestMethod.PUT)public ResponseEntity<byte[]> processTheRequest(UriComponentsBuilder componentsBuilder){byte[] bytesToReturn = ...HttpHeaders headers = new HttpHeaders();headers.setLocation( componentsBuilder.toUri() );return new ResponseEntity<byte[]>(bytesToReturn, headers, HttpStatus.CREATED);}}Wednesday, June 5, 13
  18. 18. DemonstrationWednesday, June 5, 13
  19. 19. when dumb clientsroamed the earth...Wednesday, June 5, 13
  20. 20. titleWednesday, June 5, 13
  21. 21. Wednesday, June 5, 13
  22. 22. 22Wednesday, June 5, 13
  23. 23. Wednesday, June 5, 13
  24. 24. RESTWednesday, June 5, 13
  25. 25. Roy Fielding’s “REST”• The term Representational State Transfer was introduced anddefined in 2000 by Roy Fielding in his doctoral dissertation.§ Takeaways:• Use HTTP methods explicitly.• Be stateless• an HTTP resource is uniquely described by its URLWednesday, June 5, 13
  26. 26. RestTemplate•DELETE delete(...)•GET getForObject(...)•HEAD headForHeaders(...)•OPTIONS optionsForAllow(...)•POST postForLocation(...)•PUT put(...)•any HTTP operation - exchange(...) and execute(...)Wednesday, June 5, 13
  27. 27. RestTemplate§ Google search example§ Multiple parametersRestTemplate restTemplate = new RestTemplate();String url = "http://example.com/hotels/{hotel}/bookings/{booking}";String result = restTemplate.getForObject(url, String.class, "42", “21”);RestTemplate restTemplate = new RestTemplate();String url = "https://ajax.googleapis.com/ajax/services/search/web?v=1.0&q={query}";String result = restTemplate.getForObject(url, String.class, "SpringSource");Wednesday, June 5, 13
  28. 28. the anatomy of a Spring MVC REST controller@Controllerpublic class CustomerController {@Inject private CustomerService service ;@RequestMapping(value=”/url/of/my/resource”, method = RequestMethod.GET)public @ResponseBody Customer processTheRequest( ... ) {Customer c = service.getCustomerById( id) ;return c;}}GET http://127.0.0.1:8080/url/of/my/resourceWednesday, June 5, 13
  29. 29. the anatomy of a Spring MVC REST controller@Controllerpublic class CustomerController {@RequestMapping(value=”/url/of/my/resource”, method = RequestMethod.POST)public void processTheRequest( @RequestBody Customer customer ) {// ...}}POST http://127.0.0.1:8080/url/of/my/resourceWednesday, June 5, 13
  30. 30. A Fly in the Ointment•modern browsers only speak GET and POST<filter><filter-name>hiddenHttpMethodFilter</filter-name><filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class></filter><filter-mapping><filter-name>hiddenHttpMethodFilter</filter-name><url-pattern>/</url-pattern><servlet-name>appServlet</servlet-name></filter-mapping>Wednesday, June 5, 13
  31. 31. DemonstrationWednesday, June 5, 13
  32. 32. build mobilefriendly web applicationsWednesday, June 5, 13
  33. 33. Be Where Your Users Are§ Best strategy? Develop Native• Fallback to client-optimized web applications§ Spring MVC mobile client-specific contentnegotiation and rendering• for other devicesWednesday, June 5, 13
  34. 34. Registering Spring Android@EnableWebMvc@Configurationpublic class MobileConfiguration extends WebMvcConfigurerAdapter {@Overridepublic void addArgumentResolvers(List< HandlerMethodArgumentResolver > argumentResolvers) {argumentResolvers.add(new DeviceHandlerMethodArgumentResolver());}@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new DeviceResolverHandlerInterceptor());}}Wednesday, June 5, 13
  35. 35. DemonstrationWednesday, June 5, 13
  36. 36. build native Android applicationsWednesday, June 5, 13
  37. 37. What is Spring for Android?§ does not prescribe a dependency injection solution§ provides an implementation of RestTemplateWednesday, June 5, 13
  38. 38. Some Native Android Code public Customer updateCustomer(long id, String firstName, String lastName) { RestTemplate restTemplate = new RestTemplate(); String url = “http://...8080/url/of/my/{id}”; Customer input = new Customer(id, firstName, lastName); ResponseEntity<Customer> re = restTemplate.postForEntity( url, input, Customer.class, id); HttpStatus statusOfRequest = re.getStatusCode(); if(statusOfRequest.equals( HttpStatus.OK )){Customer payloadOfResponse = re.getBody();return payloadOfResponse; } ... }Wednesday, June 5, 13
  39. 39. Make Work with§ install android development kit http://developer.android.com/sdk/index.html§ set up m2e-android http://rgladwell.github.io/m2e-android/Wednesday, June 5, 13
  40. 40. DemonstrationWednesday, June 5, 13
  41. 41. NOT CONFIDENTIAL -- TELL EVERYONE@SpringSource @StarbuxmanQuestions?Wednesday, June 5, 13
  42. 42. a more sociable SpringWednesday, June 5, 13
  43. 43. A Web of APIsWednesday, June 5, 13
  44. 44. What Problems Does OAuth Solve?• new world of many, cooperating web services• some web services may have a user context• this user context can refer to a centrally managed identity (single sign-on)• user passwords should be decoupled from the permissions a client is givenWednesday, June 5, 13
  45. 45. What Problems Does OAuth Solve?Wednesday, June 5, 13
  46. 46. What Problems Does OAuth Solve?Wednesday, June 5, 13
  47. 47. What Problems Does OAuth Solve?Wednesday, June 5, 13
  48. 48. Key Components of Spring Social§ Connection Factories• Creates connections; Handles back-end of authorization flow§ Connection Repository• Persists connections for long-term use§ Connection Factory Locator• Used by connect controller and connection repository to find connection factories§ API Bindings• Perform requests to APIs, binding to domain objects, error-handling (Facebook, Twitter, etc.)§ ConnectController• Orchestrates the web-based connection flow§ ProviderSignInController• Signs a user into an application based on an existing connection and links it to the local systemWednesday, June 5, 13
  49. 49. Bindings...Wednesday, June 5, 13
  50. 50. ...LOTS of Third Party BindingsWednesday, June 5, 13
  51. 51. Installing Spring Social@Configuration@PropertySource("classpath:social.properties")@EnableJdbcConnectionRepository@EnableFacebook(appId = "${facebook.clientId}", appSecret = "${facebook.clientSecret}")public class SocialConfiguration {@Beanpublic UserIdSource userIdSource() {return new AuthenticationNameUserIdSource();}...Wednesday, June 5, 13
  52. 52. The ConnectController@Beanpublic ConnectController connectController(ConnectionFactoryLocator connectionFactoryLocator,ConnectionRepository connectionRepository) {return new ConnectController(connectionFactoryLocator,connectionRepository);}establishes an OAuth-secured connection with the serviceprovider and returns an access tokenWednesday, June 5, 13
  53. 53. The ProviderSignInController@Beanpublic ProviderSignInController providerSignInController(final UsersConnectionRepository usersConnectionRepository,final ConnectionFactoryLocator connectionFactoryLocator) {SignInAdapter signInAdapter = ...ProviderSignInController psic = new ProviderSignInController(connectionFactoryLocator, usersConnectionRepository, signInAdapter);psic.setSignInUrl("/crm/signin.html");psic.setPostSignInUrl("/crm/customers.html");psic.setSignUpUrl("/crm/signup.html");return psic;}}establishes an OAuth-secured connection with the serviceprovider and links it to a local accountWednesday, June 5, 13
  54. 54. DemonstrationWednesday, June 5, 13
  55. 55. secure web applications withSpring SecurityWednesday, June 5, 13
  56. 56. Security is Hard, Spring Security is Easy§ Spring Security provides security services for the Spring framework§ integrates with backend identity provider services like LDAP, JAAS, OAuth, etc.§ API Bindings• there are lots of implementations of the Spring Security API that can be used in terms of a particular backendidentity provider service.§ can be used to secure web applications• form submissions, XSS-protection, resource protection§ can be used to secure method invocations§ authentication and authorization API§ cryptography implementationsWednesday, June 5, 13
  57. 57. Install Spring Security in your web.xml or Application Initializerpublic class CrmWebApplicationInitializer implements WebApplicationInitializer {@Overridepublic void onStartup(ServletContext servletContext) throws ServletException {String name = "springSecurityFilterChain";Filter filter = new DelegatingFilterProxy();FilterRegistration.Dynamic filterRegistration = servletContext.addFilter(name, filter);filterRegistration.addMappingForUrlPatterns(null, true, "/");filterRegistration.addMappingForServletNames(null, true, "spring");filterRegistration.setAsyncSupported(true);}Wednesday, June 5, 13
  58. 58. Tell Spring About Your Identities: Inline<sec:authentication-manager><sec:authentication-provider><sec:user-service><sec:user name="jlong" authorities="read" /><sec:user name="mchang" authorities="read,write" /></sec:user-service></sec:authentication-provider></sec:authentication-manager>Wednesday, June 5, 13
  59. 59. Tell Spring About Your Identities With a Custom Implementation<sec:authentication-manager><sec:authentication-provider user-service-ref = “customUserService” /></sec:authentication-manager>Wednesday, June 5, 13
  60. 60. Tell Spring About Your Identities with LDAP<sec:authentication-manager><sec:ldap-authentication-provider ... /></sec:authentication-manager>Wednesday, June 5, 13
  61. 61. Secure Access to Certain Web Resources<sec:http auto-config="true" use-expressions="true"><sec:intercept-url pattern="/secured/**" access="hasRole(ROLE_USER)" /><sec:intercept-url pattern="/**" access="isAnonymous()" /><sec:anonymous /></sec:http>Wednesday, June 5, 13
  62. 62. Install a Sign-In Form<sec:http auto-config="true" use-expressions="true"><sec:intercept-url pattern="/secured/**" access="hasRole(ROLE_USER)" /><sec:intercept-url pattern="/**" access="isAnonymous()" /><sec:anonymous /><sec:form-loginlogin-page="/crm/signin.html"default-target-url="/crm/profile.html"authentication-failure-url="/crm/signin.html?error=true" /></sec:http>Wednesday, June 5, 13
  63. 63. Install a Sign-In Form<form method="POST" action="j_spring_security_check">Username:<input name="j_username" type="text" /><br/>Password:<input name="j_password" type="password" /><br/><button type="submit" name="action" value="signin" > Sign In</button></form>Wednesday, June 5, 13
  64. 64. Programmatically AuthenticateSecurityContext securityContext = SecurityContextHolder.getContext();// read the current context authenticationAuthentication authentication = securityContext.getAuthentication();Object credentials = authentication.getCredentials(); // might be a password StringObject details = authentication.getDetails(); // might be a UserDetails object// set the current context authenticationAuthentication toAuthenticate = ...securityContext.setAuthentication( toAuthenticate );thread localWednesday, June 5, 13
  65. 65. Restrict Method Invocations@PreAuthorize(" hasRole(ROLE_USER) ")public void updateProfileInformation(String firstName, String lastName) {// ...}<sec:global-method-securitypre-post-annotations="enabled"proxy-target-class="true"/>Wednesday, June 5, 13
  66. 66. DemonstrationWednesday, June 5, 13
  67. 67. secure web serviceswith Spring Security OAuthWednesday, June 5, 13
  68. 68. What Problems Does OAuth Solve?• new world of many, cooperating web services• some web services may have a user context• this user context can refer to a centrally managed identity (single sign-on)• user passwords should be decoupled from the permissions a client is givenWednesday, June 5, 13
  69. 69. When Should I Use Spring Security OAuth?§ when you want to build an OAuth authentication server§ when your REST API has a user context that needs to be managedWednesday, June 5, 13
  70. 70. Spring Security OAuth§ Extension to Spring Security• originally a community contribution (now officially part of the project)§ Features...• endpoint management for OAuth service types• token management (persistence, authentication)• integrations for the web, as well as through standard Spring SecurityWednesday, June 5, 13
  71. 71. Tell Spring About the Clients That Might Connect<oauth:client-details-service id="clientDetailsService"><oauth:clientclient-id="html5-crm"scope="read,write"authorities="ROLE_USER"authorized-grant-types="authorization_code,implicit"resource-ids="crm"/><oauth:clientclient-id="android-crm"scope="read,write"authorities="ROLE_USER"authorized-grant-types="authorization_code,implicit"resource-ids="crm"/></oauth:client-details-service>Wednesday, June 5, 13
  72. 72. Tell Spring About the Clients That Might Connect<oauth:authorization-serverclient-details-service-ref="clientDetailsService"token-services-ref="tokenServices"><oauth:authorization-code/><oauth:implicit/><oauth:refresh-token/><oauth:client-credentials/><oauth:password/></oauth:authorization-server>@Beanpublic InMemoryTokenStore tokenStore() {return new InMemoryTokenStore();}@Beanpublic DefaultTokenServices tokenServices(InMemoryTokenStore tokenStore,ClientDetailsService clientDetailsService) {DefaultTokenServices defaultTokenServices = new DefaultTokenServices();defaultTokenServices.setTokenStore(tokenStore);defaultTokenServices.setSupportRefreshToken(true);defaultTokenServices.setClientDetailsService(clientDetailsService);return defaultTokenServices;}Wednesday, June 5, 13
  73. 73. Tell Spring About Which Resources It’s Protecting<oauth:resource-server id="resourceServerFilter"resource-id="crm" token-services-ref="tokenServices"/><sec:http pattern="/api/**"create-session="never"entry-point-ref="oauthAuthenticationEntryPoint"access-decision-manager-ref="accessDecisionManager"><sec:anonymous enabled="true"/><sec:custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER"/>...Wednesday, June 5, 13
  74. 74. Tell Spring About Which Resources It’s Protecting<oauth:resource-server id="resourceServerFilter"resource-id="crm" token-services-ref="tokenServices"/><sec:http pattern="/api/**"create-session="never"entry-point-ref="oauthAuthenticationEntryPoint"access-decision-manager-ref="accessDecisionManager"><sec:anonymous enabled="true"/><sec:custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER"/><sec:intercept-url pattern="/api/users/**/photo" method="GET"access="IS_AUTHENTICATED_ANONYMOUSLY"/><sec:intercept-url pattern="/api/users" method="GET" access="IS_AUTHENTICATED_ANONYMOUSLY"/><sec:intercept-url pattern="/api/**"access="ROLE_USER,SCOPE_READ"/>Wednesday, June 5, 13
  75. 75. Optional: Set Up an OAuth-Aware RestTemplate<oauth:rest-template id="crmRestTemplate" resource="crm" />Wednesday, June 5, 13
  76. 76. Enable Access to Certain OAuth-Context Objects in SpEL<sec:global-method-security pre-post-annotations="enabled" proxy-target-class="true"><sec:expression-handler ref="oauthExpressionHandler"/></sec:global-method-security><oauth:expression-handler id="oauthExpressionHandler"/><oauth:web-expression-handler id="oauthWebExpressionHandler"/>Wednesday, June 5, 13
  77. 77. DemonstrationWednesday, June 5, 13
  78. 78. NOT CONFIDENTIAL -- TELL EVERYONE@SpringSource @StarbuxmanQuestions?Wednesday, June 5, 13

×