GVKun编程网logo

Spring Boot:在同一项目中同时验证无状态REST API和有状态“登录” Web控制器?

14

想了解使用graphql在SpringBoot中进行身份验证的新动态吗?本文将为您提供详细的信息,此外,我们还将为您介绍关于asp.net–使用OAuth在WebAPI中进行身份验证、GraphQL与

想了解使用graphql在Spring Boot中进行身份验证的新动态吗?本文将为您提供详细的信息,此外,我们还将为您介绍关于asp.net – 使用OAuth在Web API中进行身份验证、GraphQL 与 Spring Boot 的初体验、Graphql-Mesh 如何对后端服务进行身份验证?、graphql-spring-boot上传二进制文件的新知识。

本文目录一览:

使用graphql在Spring Boot中进行身份验证

使用graphql在Spring Boot中进行身份验证

我正在使用GraphQL进行Spring Boot项目。我正在使用graphql-java-tools和graphql-spring-boot-
starter。正如您在下面的Java配置文件中看到的那样,我设法通过Spring Security配置了安全性和会话管理。

现在,“ / graphql”路径已得到保护(只能x-auth-token在请求的HTTP标头中发送“基本http身份验证”或会话令牌()才能访问它)。在任何GraphQL操作上使用“基本http身份验证”进行身份验证将启动一个新会话,并在标头中发送回新的会话令牌,并且可以将该令牌进一步用于继续该会话。

如何授予匿名用户访问某些GraphQL查询/突变的权限,以保持上述行为?

如果为了允许匿名访问而更改antMatchers("/graphql").authenticated()antMatchers("/graphql").permitAll(),则AuthenticationProvider即使尝试使用“基本http身份验证”进行身份验证,也不再调用我的自定义。

谢谢!

这是我的配置:

@Configuration@EnableWebSecurity@EnableGlobalMethodSecurity(prePostEnabled = true)public class SecurityConfig extends WebSecurityConfigurerAdapter {    @Autowired    private AuthenticationProvider authenticationProvider;    @Override    public void configure(AuthenticationManagerBuilder authenticationManagerBuilder) {        authenticationManagerBuilder.authenticationProvider(authenticationProvider);    }    @Override    protected void configure(HttpSecurity http) throws Exception {        http            .csrf().disable()            .authorizeRequests()            .antMatchers("/graphql").authenticated()            .and()            .requestCache()            .requestCache(new NullRequestCache())            .and()            .httpBasic()            .and()            .headers()            .frameOptions().sameOrigin() // needed for H2 web console            .and()            .sessionManagement()            .maximumSessions(1)            .maxSessionsPreventsLogin(true)            .sessionRegistry(sessionRegistry());    }    @Bean    public SessionRegistry sessionRegistry() {        return new SessionRegistryImpl();    }    @Bean    public HttpSessionEventPublisher httpSessionEventPublisher() {        return new HttpSessionEventPublisher();    }}@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 180)public class HttpSessionConfig {    @Bean    public HttpSessionStrategy httpSessionStrategy() {        return new HeaderHttpSessionStrategy();    }}

答案1

小编典典

而不是.antMatchers("/graphql").authenticated()我们使用了.antMatchers("/graphql").permitAll(),然后我们删除了,.httpBasic()并且还删除了自定义AuthenticationProvider。现在,安全性配置如下所示:

@Configuration@EnableWebSecurity@EnableGlobalMethodSecurity(prePostEnabled = true)public class SecurityConfig extends WebSecurityConfigurerAdapter {    @Override    protected void configure(HttpSecurity http) throws Exception {        http            .csrf().disable()            .authorizeRequests()            .antMatchers("/graphql").permitAll()            .and()            .requestCache()            .requestCache(new NullRequestCache())            .and()            .headers()            .frameOptions().sameOrigin() // needed for H2 web console            .and()            .sessionManagement()            .maximumSessions(1)            .maxSessionsPreventsLogin(true)            .sessionRegistry(sessionRegistry());    }    @Bean    public SessionRegistry sessionRegistry() {        return new SessionRegistryImpl();    }    @Bean    public HttpSessionEventPublisher httpSessionEventPublisher() {        return new HttpSessionEventPublisher();    }}

然后,我们为登录创建了一个变异,该变异接受用户的凭据并返回会话令牌。这是graphql模式:

login(credentials: CredentialsInputDto!): Stringinput CredentialsInputDto {    username: String!    password: String!}

基本上,我们在自定义AuthenticationProvider中拥有的代码进入了登录操作所调用的服务:

public String login(CredentialsInputDto credentials) {    String username = credentials.getUsername();    String password = credentials.getPassword();    UserDetails userDetails = userDetailsService.loadUserByUsername(username);    ... credential checks and third party authentication ...    Authentication authentication = new UsernamePasswordAuthenticationToken(username, password, userDetails.getAuthorities());    SecurityContextHolder.getContext().setAuthentication(authentication);    httpSession.setAttribute("SPRING_SECURITY_CONTEXT", SecurityContextHolder.getContext());    return httpSession.getId();}

关键是我们准备了具有经过身份验证的用户的身份验证的会话上下文,然后将其保存(以redis格式)作为称为“
SPRING_SECURITY_CONTEXT”的会话属性。当您发出一个请求,该请求设置了“ x-auth-
token”标头并设置了从登录操作获取的会话令牌的值时,spring便能够自动恢复上下文。

现在,由于.antMatchers("/graphql").permitAll()在服务层中并且在服务层中,也允许匿名调用,在公共方法上,我们可以使用如下注释:@Preauthorize("isAnonymous()OR
hasRole("USER")")

asp.net – 使用OAuth在Web API中进行身份验证

asp.net – 使用OAuth在Web API中进行身份验证

我正在使用ASP.Net MVC5开发一个项目,该MVC5还包括一个Web API. API仅供内部使用.我正在使用OWIN库来提供身份验证.

我很难想出如何通过API正确实现身份验证.我计划使用OAuth 2.0,但OAuth的问题是用户需要通过浏览器页面登录,而不是本机登录屏幕.所以我想知道是否有可能以某种方式跳过浏览器.

我发现了this的例子,它创建了自己的OAuth授权服务器.但是它并没有显示如何使登录本地化.

解决方法

如果它是一个高度信任的客户端,那么您可以使用OAuth2资源所有者密码流.你可以看看VS2013 SPA模板和/或阅读这篇文章:

http://leastprivilege.com/2013/11/13/embedding-a-simple-usernamepassword-authorization-server-in-web-api-v2/

GraphQL 与 Spring Boot 的初体验

GraphQL 与 Spring Boot 的初体验

GraphQL

感谢您的阅读,本文由 杨斌的博客 版权所有。
如若转载,请注明出处:杨斌的博客(https://y0ngb1n.github.io/a/g...)

项目已托管于 GitHub:y0ngb1n/spring-boot-samples,欢迎 Star, Fork


GraphQL 既是一种用于 API 的查询语言也是一个满足你数据查询的运行时。 GraphQL 对你的 API 中的数据提供了一套易于理解的完整描述,使得客户端能够准确地获得它需要的数据,而且没有任何冗余,也让 API 更容易地随着时间推移而演进,还能用于构建强大的开发者工具。

定义 Schema

# src/main/resources/schema.graphql
schema {
  query: Query
}

type Query {
  allBooks: [Book]
  book(id: String): Book
}

type Book {
  isbn: String
  title: String
  publisher: String
  authors: [String]
  publishedDate: String
}

加载并解析上面定义的 Schema

@Service
public class GraphQLService {

  @Value("classpath:schema.graphql")
  private Resource resource;

  @Getter
  private GraphQL graphQL;
  @Autowired
  private AllBooksDataFetcher allBooksDataFetcher;
  @Autowired
  private BookDataFetcher bookDataFetcher;

  @PostConstruct
  private void loadSchema() throws IOException {
    // 获取本地定义的 Schema 文件
    File schemaFile = resource.getFile();
    // 解析 Schema 文件
    TypeDefinitionRegistry typeRegistry = new SchemaParser().parse(schemaFile);
    RuntimeWiring wiring = buildRuntimeWiring();
    GraphQLSchema schema = new SchemaGenerator().makeExecutableSchema(typeRegistry, wiring);
    graphQL = GraphQL.newGraphQL(schema).build();
  }

  private RuntimeWiring buildRuntimeWiring() {
    return RuntimeWiring.newRuntimeWiring()
      .type("Query", typeWiring -> typeWiring
        .dataFetcher("allBooks", allBooksDataFetcher)
        .dataFetcher("book", bookDataFetcher)
      ).build();
  }
}

提供 DataFetcher

相当于提供 Schema 中的 Query 实现:

type Query {
  allBooks: [Book]
  book(id: String): Book
}

AllBooksDataFetcher 对应实现 allBooks: [Book]

@Component
public class AllBooksDataFetcher implements DataFetcher<List<Book>> {

  @Autowired
  private BookRepository bookRepository;

  @Override
  public List<Book> get(DataFetchingEnvironment dataFetchingEnvironment) {
    return bookRepository.findAll();
  }
}

BookDataFetcher 对应实现 book(id: String): Book

@Component
public class BookDataFetcher implements DataFetcher<Book> {

  @Autowired
  private BookRepository bookRepository;

  @Override
  public Book get(DataFetchingEnvironment dataFetchingEnvironment) {
    String isn = dataFetchingEnvironment.getArgument("id");
    return bookRepository.findById(isn).orElse(null);
  }
}

提供 GraphQL API

@RestController
@RequestMapping(path = "/v1/books")
public class BookController {

  @Autowired
  private GraphQLService graphQLService;

  @PostMapping
  public ResponseEntity<Object> getAllBooks(@RequestBody String query) {
    ExecutionResult execute = graphQLService.getGraphQL().execute(query);
    return new ResponseEntity<>(execute, HttpStatus.OK);
  }
}

启动并测试

$ mvn install
...
[INFO] BUILD SUCCESS
...
$ mvn spring-boot:run
...
2019-08-24 19:35:11.700  INFO 14464 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''''
2019-08-24 19:35:11.702  INFO 14464 --- [           main] i.g.y.s.graphql.GraphQLApplication       : Started GraphQLApplication in 16.808 seconds (JVM running for 25.601)

查询部分字段

$ curl -X POST \
  http://127.0.0.1:8080/v1/books \
  -H ''Content-Type: text/plain'' \
  -d ''{
    allBooks {
      isbn
      title
  }
}'' | jq
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   579    0   524  100    55  34933   3666 --:--:-- --:--:-- --:--:-- 38600
{
  "errors": [],
  "data": {
    "allBooks": [
      {
        "isbn": "9787111213826",
        "title": "Java 编程思想(第4版)"
      },
      ...
    ]
  },
  "extensions": null,
  "dataPresent": true
}
$ curl -X POST \
  http://127.0.0.1:8080/v1/books \
  -H ''Content-Type: text/plain'' \
  -d ''{
    book(id: "9787121362132") {
      title
  }
}'' | jq
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   210    0   159  100    51   1691    542 --:--:-- --:--:-- --:--:--  2234
{
  "errors": [],
  "data": {
    "book": {
      "title": "高可用可伸缩微服务架构:基于 Dubbo、Spring Cloud 和 Service Mesh"
    }
  },
  "extensions": null,
  "dataPresent": true
}

查询全部字段

$ curl -X POST \
  http://127.0.0.1:8080/v1/books \
  -H ''Content-Type: text/plain'' \
  -d ''{
    allBooks {
      isbn
      title
      authors
      publisher
      publishedDate
  }
}'' | jq
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  1139    0  1044  100    95    750     68  0:00:01  0:00:01 --:--:--   818
{
  "errors": [],
  "data": {
    "allBooks": [
      {
        "isbn": "9787111213826",
        "title": "Java 编程思想(第4版)",
        "authors": [
          "Bruce Eckel"
        ],
        "publisher": "机械工业出版社",
        "publishedDate": "2007-06-01"
      },
      ...
    ]
  },
  "extensions": null,
  "dataPresent": true
}
$ curl -X POST \
  http://127.0.0.1:8080/v1/books \
  -H ''Content-Type: text/plain'' \
  -d ''{
    book(id: "9787121362132") {
      title
      authors
      publisher
      publishedDate
  }
}'' | jq
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   421    0   320  100   101   312k    98k --:--:-- --:--:-- --:--:--  411k
{
  "errors": [],
  "data": {
    "book": {
      "title": "高可用可伸缩微服务架构:基于 Dubbo、Spring Cloud 和 Service Mesh",
      "authors": [
        "程超",
        "梁桂钊",
        "秦金卫",
        "方志斌",
        "张逸",
        "杜琪",
        "殷琦",
        "肖冠宇"
      ],
      "publisher": "电子工业出版社",
      "publishedDate": "2019-05-01"
    }
  },
  "extensions": null,
  "dataPresent": true
}

查询多个数据

$ curl -X POST \
  http://127.0.0.1:8080/v1/books \
  -H ''Content-Type: text/plain'' \
  -d ''{
    allBooks {
      isbn
      title
    }
    book(id: "9787121362132") {
      title
      authors
      publisher
      publishedDate
  }
}'' | jq
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   930    0   785  100   145   3866    714 --:--:-- --:--:-- --:--:--  4581
{
  "errors": [],
  "data": {
    "allBooks": [
      {
        "isbn": "9787111213826",
        "title": "Java 编程思想(第4版)"
      },
      {
        "isbn": "9787111421900",
        "title": "深入理解 Java 虚拟机:JVM 高级特性与最佳实践(第2版)"
      },
      {
        "isbn": "9787115221704",
        "title": "重构 改善既有代码的设计(第2版)"
      },
      {
        "isbn": "9787121362132",
        "title": "高可用可伸缩微服务架构:基于 Dubbo、Spring Cloud 和 Service Mesh"
      },
      {
        "isbn": "9787302392644",
        "title": "人月神话(40周年中文纪念版)"
      }
    ],
    "book": {
      "title": "高可用可伸缩微服务架构:基于 Dubbo、Spring Cloud 和 Service Mesh",
      "authors": [
        "程超",
        "梁桂钊",
        "秦金卫",
        "方志斌",
        "张逸",
        "杜琪",
        "殷琦",
        "肖冠宇"
      ],
      "publisher": "电子工业出版社",
      "publishedDate": "2019-05-01"
    }
  },
  "extensions": null,
  "dataPresent": true
}

综上可见,API 不变只改动了查询的内容,就会自动响应不同的结果。


参考链接

  • https://graphql.org/
  • https://developer.github.com/v4/
  • https://www.baeldung.com/graphql
  • https://www.baeldung.com/spri...
  • https://youtu.be/zX2I7-aIldE
  • https://leader.js.cool/#/basi...
  • https://github.com/glennreyes...
  • 全面解析 GraphQL,携程微服务背景下的前后端数据交互方案
  • 前端er了解 GraphQL,看这篇就够了
  • GraphQL 之路
  • 谈谈 GraphQL 的历史、组件和生态系统

Graphql-Mesh 如何对后端服务进行身份验证?

Graphql-Mesh 如何对后端服务进行身份验证?

如何解决Graphql-Mesh 如何对后端服务进行身份验证??

我想知道我们如何使用基于 oAuth 或 SAML 的身份验证的后端服务对 graphql-mesh 服务器进行身份验证。有一些例子我看到了 API-KEY 的使用,但是这个 API-KEY 是如何获得的,我们是否需要在“纱线网格”之前调用一些方法来验证和存储 API-KEY 某处?

我错过了什么吗?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

graphql-spring-boot上传二进制文件

graphql-spring-boot上传二进制文件

如何解决graphql-spring-boot上传二进制文件?

Spring boot的嵌入式Tomcat默认为Servlet 3.x多部分支持。GraphQL Java servlet支持公用FileUpload。为了使工作正常,您必须禁用Spring boots默认的multipart配置,例如:

在pom.xml中为commons-fileupload添加Maven依赖项

    <dependency>
        <groupId>commons-fileupload</groupId>
        <artifactId>commons-fileupload</artifactId>
        <version>1.3.3</version>
    </dependency>

Application.yml

spring:
    servlet:
      multipart:
         enabled: false

Spring Boot应用程序类

@EnableAutoConfiguration(exclude={MultipartAutoConfiguration.class})

然后在您的@Configuration中添加一个@Bean

@Bean(name = "multipartResolver")
public CommonsMultipartResolver multipartResolver() {
    CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
    multipartResolver.setMaxUploadSize(100000);
    return multipartResolver;
}

现在,您可以在GraphQL上下文中找到上载的多部分文件,因为它们会自动映射到:

environment -> context -> files

可从

突变的实现示例:

@Component
public class Mutation implements GraphQLMutationResolver {

    @Autowired
    private TokenService tokenService;

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private UserService userService;

    @Autowired
    private ProjectRepository repository;

    @Autowired
    @Qualifier( value = "modeshape" )
    private StorageService storageService;

    @GraphQLField @GraphQLRelayMutation
    public ProjectItem createProject( CreateProjectInput input, DataFetchingEnvironment environment ) {
        Project project = new Project( input.getName() );
        project.setDescription( input.getDescription() );
        GraphQLContext context = environment.getContext();
        Optional<Map<String, List<FileItem>>> files = context.getFiles();
        files.ifPresent( keys -> {
            List<FileItem> file = keys.get( "file" );
            List<StorageService.FileInfo> storedFiles = file.stream().map( f -> storageService.store( f, "files", true ) ).collect( Collectors.toList() );
            project.setFile( storedFiles.get( 0 ).getUuid() );
        } );
        repository.save( project );
        return new ProjectItem( project );
    }
class CreateProjectInput {
    private String name;
    private String description;
    private String clientMutationId;

    @GraphQLField
    public String getName() {
        return name;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription( String description ) {
        this.description = description;
    }

    @GraphQLField
    public String getClientMutationId() {
        return clientMutationId;
    }
}

解决方法

我正在尝试上传GraphQL突变和图像作为应用程序/表单数据。GraphQL部分正在工作,但是我想“保存”上载的二进制文件并将路径添加到GraphQL数据。在createGraphQLContext中,我可以访问HttpServletRequest,但是(多个)部分为空。我使用带有嵌入式tomcat
8.5和提供的GraphQL Java工具的graphql-spring-boot-starter

这是我对/ graphql的Relay Modern调用

------WebKitFormBoundaryWBzwQyVX0TvBTIBD
Content-Disposition: form-data; name="query"

mutation CreateProjectMutation(
  $input: ProjectInput!
) {
  createProject(input: $input) {
    id
    name
  }
}

------WebKitFormBoundaryWBzwQyVX0TvBTIBD
Content-Disposition: form-data; name="variables"

{"input":{"name":"sdasas"}}
------WebKitFormBoundaryWBzwQyVX0TvBTIBD
Content-Disposition: form-data; name="file"; filename="51zvT5zy44L._SL500_AC_SS350_.jpg"
Content-Type: image/jpeg


------WebKitFormBoundaryWBzwQyVX0TvBTIBD--

在我中,@Component public class MyGraphQLContextBuilder implements GraphQLContextBuilder我有权HttpServletRequest使用以下文件访问该文件:req.getPart( "file" )

但是我在请求中的部分是空的 intellij调试器

我已将此添加到我的application.yml

spring:
    http:
      multipart:
        enabled: true
        file-size-threshold: 10MB
        location: /tmp
        max-file-size: 10MB
        max-request-size: 15MB
        resolve-lazily: false

并尝试使用不同的@configuration启用多部分配置,但部分仍然为空。

@Configuration
public class MultipartConfig {

    @Bean
    public MultipartResolver multipartResolver() {
        StandardServletMultipartResolver resolver = new StandardServletMultipartResolver();
        return resolver;
    }

}

import javax.servlet.MultipartConfigElement;
import javax.servlet.ServletRegistration.Dynamic;

import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

public class MyInitializer
        extends AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[] {};
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[] { MultipartConfig.class };
    }

    @Override
    protected String[] getServletMappings() {
        return new String[] { "/graphql" };
    }

    @Override
    protected void customizeRegistration(Dynamic registration) {

        //Parameters:-
        //   location - the directory location where files will be stored
        //   maxFileSize - the maximum size allowed for uploaded files
        //   maxRequestSize - the maximum size allowed for multipart/form-data requests
        //   fileSizeThreshold - the size threshold after which files will be written to disk
        MultipartConfigElement multipartConfig = new MultipartConfigElement("/tmp",1048576,10485760,0);
        registration.setMultipartConfig(multipartConfig);
    }
}

我不知道该怎么办。希望有人可以帮助我。

谢谢。

今天的关于使用graphql在Spring Boot中进行身份验证的分享已经结束,谢谢您的关注,如果想了解更多关于asp.net – 使用OAuth在Web API中进行身份验证、GraphQL 与 Spring Boot 的初体验、Graphql-Mesh 如何对后端服务进行身份验证?、graphql-spring-boot上传二进制文件的相关知识,请在本站进行查询。

最近很多小伙伴都在问Spring Boot:在同一项目中同时验证无状态REST API和有状态“登录” Web控制器?这两个问题,那么本篇文章就来给大家详细解答一下,同时本文还将给你拓展angularjs – Google OAuth 2.0.页面刷新后,javascript API不会保持“登录”状态、asp.net-web-api – WebApi:如何将状态从过滤器传递给控制器?、asp.net-web-api – 在Azure Service Fabric中,无状态Web API和ASP.NET Core Web API之间的差异是什么?、http 协议,web应用中的有状态和无状态等相关知识,下面开始了哦!

本文目录一览:

Spring Boot:在同一项目中同时验证无状态REST API和有状态“登录” Web控制器?

Spring Boot:在同一项目中同时验证无状态REST API和有状态“登录” Web控制器?

因此,我有一个包含REST API的应用程序,该IETF设备上的自定义Java应用程序使用了REST
API,而无需用户交互。我还有一个Web应用程序,该应用程序需要状态会话来维护用户登录。

可以使用Spring Security来不同地验证对我的API和Web控制器的请求吗?我应该对REST API使用哪种形式的身份验证?

答案1

小编典典

实现您所寻找的一种方法是在Spring Security中具有2种配置。例如

注重antMatcher匹配 不匹配 小号
)。在antMatcher将控制在什么网址设置您的整个配置适用即FormLoginWebSecurityConfigurerAdapter在下面的例子将仅适用于URI匹配/api/test/**。当然,您可以antMatcher在其中一个配置中定义唯一的名称,即config1,在这种情况下,另一个配置将是全部捕获(即,捕获与config1不匹配的所有内容)

@EnableWebSecurity@Configurationpublic class SecurityConfig {    @Configuration    @Order(1)                                                            public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {        @Override               public void configure(AuthenticationManagerBuilder auth)           throws Exception {                        auth.inMemoryAuthentication().withUser("user").password("user").roles("USER");            auth.inMemoryAuthentication().withUser("admin").password("admin").roles("ADMIN");        }        protected void configure(HttpSecurity http) throws Exception {http.sessionManagement()        .sessionCreationPolicy(SessionCreationPolicy.STATELESS)            http                .antMatcher("/api/v1/**")                                               .authorizeRequests()                .antMatchers("/api/v1/**").authenticated()                    .and()                .httpBasic();        }    }    @Configuration    @Order(2)    public static class FormLoginWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {        @Override               public void configure(AuthenticationManagerBuilder auth)           throws Exception {            auth.inMemoryAuthentication().withUser("user1").password("user").roles("USER");            auth.inMemoryAuthentication().withUser("admin1").password("admin").roles("ADMIN");        }        @Override        protected void configure(HttpSecurity http) throws Exception {http.sessionManagement()        .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED); // CONFIGURE TYPE OF SESSION POLICY            http                .antMatcher("/api/test/**")                .authorizeRequests()                .antMatchers("/api/test/**").authenticated()                    .and()                .formLogin();        }    }}

angularjs – Google OAuth 2.0.页面刷新后,javascript API不会保持“登录”状态

angularjs – Google OAuth 2.0.页面刷新后,javascript API不会保持“登录”状态

我正在使用谷歌用户身份验证开发AngularJS应用程序.我采用了angular-google-plus软件包(一个使用Google Api处理登录的Angular模块).

在它的核心,登录将使用gapi对象:

gapi.auth.authorize(…)

页面不刷新时一切正常.例如,我可以通过以下方式从API获取当前用户:
gapi.client.oauth2.userinfo.get().execute(function(){…})但是,当我刷新页面时,状态不会被保留.

刷新页面后,为了保持“Logged-In”状态,我需要做什么?似乎谷歌api“忘记”了这个州.

解决方法

我觉得你的代码不熟悉……它真的是OAuth 2.0吗?
我认为你在谈论 Google Sign-In JavaScript client,因为你提到页面刷新.

我相信你不能立即得到像gapi.client.oauth2.userinfo这样的信息,因为没有代码可以等待初始化实例.

然后执行以下操作:

gapi.auth2.init({client_id: "...",...}).then(function(googleAuth) { // onInit
  console.log(googleAuth.isSignedIn.get());
},function() { // onError
});

asp.net-web-api – WebApi:如何将状态从过滤器传递给控制器?

asp.net-web-api – WebApi:如何将状态从过滤器传递给控制器?

我正在拉动一些用户数据的动作过滤器,并且可以在控制器的操作中使用一些数据,但不完全确定如何将数据从过滤器传递到控制器。
在MVC中,我可能会使用会话或HttpContext.Items,但它不可用于web api。另一个选择是使用ThreadStatic,但我认为必须有更好的解决方案?

解决方法

您可以使用Request.Properties字典来做到这一点。

在过滤器中:

MyType myObject = //initialize from somwhere
actionContext.Request.Properties.Add("mykey",myObject);

然后你可以在控制器中检索它:

object myObject;
Request.Properties.TryGetValue("mykey",out myObject);
//cast to MyType

这种方法的优点是当前的请求实例可以在Web API管道中的任何地方使用,因此您可以访问此对象,即在Formatter或MessageHandler中。

asp.net-web-api – 在Azure Service Fabric中,无状态Web API和ASP.NET Core Web API之间的差异是什么?

asp.net-web-api – 在Azure Service Fabric中,无状态Web API和ASP.NET Core Web API之间的差异是什么?

我没有挖那么多,但两者的优点和缺点是什么……
似乎它们是多余的,显然核心版本是实验性的,可能不适用于许多核心库,如Odata和Entity Framework

解决方法

tl / dr:无状态Web API是较旧的“经典”Web API. ASP.NET Core是所有新功能的新功能.

更多细节:

无状态Web API模板:

>基于OWIN的“经典”ASP.NET Web API 2.不支持MVC(没有Razor服务器端渲染).
>仅限完整的.NET Framework.
>在Visual Studio 2015中使用“经典”.NET项目类型(.csproj).
>使用Katana作为Web主机,它是在System.Net.HttpListener上构建的,它本身使用Windows HTTP Server API(http.sys).

ASP.NET核心模板:

>新的ASP.NET Core,它结合了MVC和Web API,并提供了Razor服务器端呈现和ASP.NET的大量新功能.
>完整的.NET Framework或.NET Core,但目前Service Fabric中仅支持完整的.NET Framework.
>在Visual Studio 2015中使用新的.NET项目类型(.xproj).在VS 2015中为此项目类型的工具被视为“预览”并将保持不变.工具仅在较新的Visual Studio 2017中被视为“生产”(它已被更改回.csproj).这就是我们目前在VS 2015中同时拥有两个项目模板的原因.
>使用WebListener or Kestrel作为Web主机.

> WebListener也基于http.sys,完全支持.> Kestrel基于完全不同的跨平台库(libuv),在当前状态下,我们不建议将其放在面向Internet的生产应用程序中,而不使用反向代理来提供DoS保护.

http 协议,web应用中的有状态和无状态

http 协议,web应用中的有状态和无状态

1、什么是Web应用程序的无状态性?
说基于http协议的web应用程序是请求——应答模式是无状态的,我们可以这样理解:每次的请求都是独立的,它的执行情况和结果与前面的请求和之后的请求是无直接关系的,它不会受前面的请求应答情况直接影响,也不会直接影响后面的请求应答情况。

2、如何使我们的web应用是有状态?

http协议的基础上,web应用引入cookies, session,application来保持web应用之间的状态。

注:
cookies,sessionapplication都不是标准协议,但是各种网络应用提供商,实现语言、web容器都默认支持它。当然这种支持与对网络标准协议的支持是不同的,标准协议规定的接口,而这种机制只是规定了思想。

其实从我们上面的分析看来,application不应该被视为这种意义上出现的维护状态的机制。它是决定怎么应用程序的“配制文件”。但是如果你从这种状态维持机制所覆盖的范围来推导,你会发现,application好像也算得上。

Session所控制的范围是一个session。一个会话,会话从第一次访问服务器开始存在,到服务器调用session.invalidator()(可能是超时,可能是其它原因)。

Cookies所控制的范围有它自己的定义(session没有直接的关系),可以长可以短。只要服务器放在用户文件系统中的cookies没有被删除,至少服务器还识别它。它的控制范围就是还在的。

这个角度上讲,SessionCookies都可以归为跨页面的状态。但是session跨不出一次会话,Cookies跨不出两端的限制。

Application,则是关联这个网络应用程序的。


举例:

有人将web应用中有无状态的情况,比着顾客逛商店的情景。

顾客:浏览器访问方;

商店:web服务器;

一次购买:一次http访问

我们知道,上一次顾客购买,并不代表顾客下一个小时一定会买(当然也不能代表不会)。也就是说同一个顾客的不同购买之间的关系是不定的。所以说实在的,这种情况下,让商店保存所有的顾客购买的信息,等到下一次购买可以知道这个顾客以前购买的内容代价非常大的。所以商店为了避免这个代价,索性就认为每次的购买都是一次独立的新的购买。浅台词:商店不区分对待老顾客和新过客。这就是无状态的。

但是,商店为了提高收益。她是想鼓励顾客购买的。所以告诉你,只要你在一个月内购买了5瓶以上的啤酒,就送你一个酒杯。

我们看看这种情况我们怎么去实现呢?

A,给顾客发放一个磁卡,里面放有顾客过去的购买信息。

这样商店就可以知道了。这就是cookie.

B,给顾客发放一个唯一号码,号码制定的顾客的消费信息,存储在商店的服务器中。这就是session

最后,商店可以全局的决定,是5瓶为送酒杯还是6瓶。这就是application

其实,这些机制都是在无状态的传统购买过程中加入了一点东西,使整个过程变得有状态。Web应用就是这样的。

关于Spring Boot:在同一项目中同时验证无状态REST API和有状态“登录” Web控制器?的问题我们已经讲解完毕,感谢您的阅读,如果还想了解更多关于angularjs – Google OAuth 2.0.页面刷新后,javascript API不会保持“登录”状态、asp.net-web-api – WebApi:如何将状态从过滤器传递给控制器?、asp.net-web-api – 在Azure Service Fabric中,无状态Web API和ASP.NET Core Web API之间的差异是什么?、http 协议,web应用中的有状态和无状态等相关内容,可以在本站寻找。

本文标签: