自定义 Spring Security 应用程序中的无限循环

2023-11-30

我们尝试用现有的 Spring Security Basic Login 替换开源应用程序中的 REST-API,以实现使用令牌的自定义登录。我读过这篇关于该主题的博文:http://javattitude.com/2014/06/07/spring-security-custom-token-based-rest-authentication/

当请求没有名为“Cookie”的标头时,我会得到正确的 401 - 未经授权的响应(预期行为)。当请求具有有效令牌时,我会出现无限循环,导致java.lang.StackOverflowError:

    Exception in thread "http-bio-8080-exec-45" java.lang.StackOverflowError
        at org.apache.tomcat.util.http.NamesEnumerator.<init>(MimeHeaders.java:402)
        at org.apache.tomcat.util.http.MimeHeaders.names(MimeHeaders.java:228)
        at org.apache.catalina.connector.Request.getHeaderNames(Request.java:2108)
        at org.apache.catalina.connector.RequestFacade.getHeaderNames(RequestFacade.java:726)
        at javax.servlet.http.HttpServletRequestWrapper.getHeaderNames(HttpServletRequestWrapper.java:103)
        at javax.servlet.http.HttpServletRequestWrapper.getHeaderNames(HttpServletRequestWrapper.java:103)
        at javax.servlet.http.HttpServletRequestWrapper.getHeaderNames(HttpServletRequestWrapper.java:103)
        at javax.servlet.http.HttpServletRequestWrapper.getHeaderNames(HttpServletRequestWrapper.java:103)
        at javax.servlet.http.HttpServletRequestWrapper.getHeaderNames(HttpServletRequestWrapper.java:103)
        at javax.servlet.http.HttpServletRequestWrapper.getHeaderNames(HttpServletRequestWrapper.java:103)
at org.activiti.rest.security.CustomTokenAuthenticationFilter.attemptAuthentication(CustomTokenAuthenticationFilter.java:43)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:211)
    at org.activiti.rest.security.CustomTokenAuthenticationFilter.doFilter(CustomTokenAuthenticationFilter.java:86)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:101)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:65)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:101)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:166)
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:344)
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:261)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:749)
    at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:487)
    at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:412)
    at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:339)
    at org.springframework.security.web.firewall.RequestWrapper$FirewalledRequestAwareRequestDispatcher.forward(RequestWrapper.java:132)
    at org.activiti.rest.security.TokenSimpleUrlAuthenticationSuccessHandler.onAuthenticationSuccess(TokenSimpleUrlAuthenticationSuccessHandler.java:30)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.successfulAuthentication(AbstractAuthenticationProcessingFilter.java:331)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.successfulAuthentication(AbstractAuthenticationProcessingFilter.java:298)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:235)
    at org.activiti.rest.security.CustomTokenAuthenticationFilter.doFilter(CustomTokenAuthenticationFilter.java:86)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:101)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:65)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:101)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:166)
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:344)
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:261)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:749)
    at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:487)
    at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:412)
    at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:339)
    at org.springframework.security.web.firewall.RequestWrapper$FirewalledRequestAwareRequestDispatcher.forward(RequestWrapper.java:132)
    at org.activiti.rest.security.TokenSimpleUrlAuthenticationSuccessHandler.onAuthenticationSuccess(TokenSimpleUrlAuthenticationSuccessHandler.java:30)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.successfulAuthentication(AbstractAuthenticationProcessingFilter.java:331)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.successfulAuthentication(AbstractAuthenticationProcessingFilter.java:298)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:235)
    at org.activiti.rest.security.CustomTokenAuthenticationFilter.doFilter(CustomTokenAuthenticationFilter.java:86)

我的 Spring Security 配置如下所示:

@Configuration
@EnableWebSecurity
@EnableWebMvcSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

  @Bean
  public AuthenticationProvider authenticationProvider() {
    return new BasicAuthenticationProvider();
  }

  @Autowired
  AuthenticationProvider basicAuthenticationProvider;

  @Bean
  public CustomTokenAuthenticationFilter customTokenAuthenticationFilter(){
      System.out.println("+++ create new CustomTokenAuthenticationFilter for path=/**");
      return new CustomTokenAuthenticationFilter("/**");
  };

  @Autowired
  CustomTokenAuthenticationFilter customTokenAuthenticationFilter;

  @Override
  protected void configure(HttpSecurity http) throws Exception {
      System.out.println("init of http security START");
     http
     .authenticationProvider(authenticationProvider())
     .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
     .csrf().disable()
     .authorizeRequests()
       .anyRequest().authenticated()
     .and()//.authenticationProvider(basicAuthenticationProvider);
     .addFilterBefore(customTokenAuthenticationFilter,  BasicAuthenticationFilter.class)
     .httpBasic();
       //.and().addFilter(filter);
    System.out.println("init of http security DONE");
  }
}

我已经尝试更改 URL 映射/** to /activiti-rest/**但随后,基本身份验证再次启动。

这是我的自定义令牌身份验证过滤器:

public class CustomTokenAuthenticationFilter extends AbstractAuthenticationProcessingFilter {

    private static final Logger logger = LoggerFactory.getLogger(CustomTokenAuthenticationFilter.class);
    public CustomTokenAuthenticationFilter(String defaultFilterProcessesUrl) {
        super(defaultFilterProcessesUrl);
        super.setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher(defaultFilterProcessesUrl));
        setAuthenticationManager(new NoOpAuthenticationManager());
        setAuthenticationSuccessHandler(new TokenSimpleUrlAuthenticationSuccessHandler());
    }


    public final String HEADER_SECURITY_TOKEN = "Cookie";//"LdapToken"; 


    /**
     * Attempt to authenticate request - basically just pass over to another method to authenticate request headers 
     */
    @Override public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {
        Enumeration<String> headerNames = request.getHeaderNames();
        int i = 0;
        while (headerNames.hasMoreElements()){
            String key = (String) headerNames.nextElement();
            String value = request.getHeader(key);
            System.out.println("+++ key["+i+"]" +key);
            System.out.println("+++ val["+i+"]" +value);
            i++;
        }
        String token = request.getHeader(HEADER_SECURITY_TOKEN);
        logger.info("token found:"+token);
        System.out.println("+++ token found:"+token);
        AbstractAuthenticationToken userAuthenticationToken = authUserByToken(token);
        if(userAuthenticationToken == null) throw new AuthenticationServiceException(MessageFormat.format("Error | {0}", "Bad Token"));
        System.out.println("+++ userAuthenticationToken:"+userAuthenticationToken.toString());
        return userAuthenticationToken;
    }


    /**
     * authenticate the user based on token
     * @return
     */
    private AbstractAuthenticationToken authUserByToken(String token) {
        if(token==null) {
            System.out.println("+++ i shouldn't be null +++");
            return null;
        }
        AbstractAuthenticationToken authToken = new JWTAuthenticationToken(token);
        try {
            return authToken;
        } catch (Exception e) {
            System.out.println(e);
            logger.error("Authenticate user by token error: ", e);
        }
        return authToken;
    }


    @Override
    public void doFilter(ServletRequest req, ServletResponse res,
            FilterChain chain) throws IOException, ServletException {
        System.out.println("++++++++++++++++++++++++++++++ doFilter ");
        super.doFilter(req, res, chain);
    }
}

还有我的自定义成功处理程序。我认为这会导致无限循环,但我不明白为什么:

public class TokenSimpleUrlAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {

    @Override
    protected String determineTargetUrl(HttpServletRequest request,
            HttpServletResponse response) {
        System.out.println("+++ yuhuuu determineTargetUrl+++");
        String context = request.getContextPath();
        String fullURL = request.getRequestURI();
        String url = fullURL.substring(fullURL.indexOf(context)+context.length());
        return url;
    }

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request,
            HttpServletResponse response, Authentication authentication)
            throws IOException, ServletException {
        System.out.println("+++ yuhuuu onAuthenticationSuccess+++");
        String url = determineTargetUrl(request,response);
        request.getRequestDispatcher(url).forward(request, response);
    }
}

所有其他类(NoOpAuthenticationManager 和 RestAuthenticationEntryPoint)与本博文中的完全相同。

如果有人能给我一个提示,什么会导致这个无限循环,那就太好了。正如我所说,它仅在请求具有有效令牌时发生。

谢谢并致以诚挚的问候 本


您的编码方法是有效的。不过,我可以为您提供一种略有不同但有效的方法。在开始解释解决方案之前,先看一下代码:

WebSecurityConfig.java

@Configuration
@EnableWebMvcSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests().
    antMatchers("/restapi").hasRole("USER")
    .and().addFilterBefore(new SsoTokenAuthenticationFilter(authenticationManager()), BasicAuthenticationFilter.class).httpBasic()
    .and().authorizeRequests().antMatchers("/**").permitAll().anyRequest().authenticated();
}

@Override
protected void configure(AuthenticationManagerBuilder auth)
        throws Exception {
    // The order is important! During runtime Spring Security tries to find Provider-Implementations that
    // match the UsernamePasswordAuthenticationToken (which will be created later..). We must make sure
    // that daoAuthenticationProvider matches first. Why? Hard to explain, I figured it out with the debugger.
    auth.authenticationProvider(daoAuthenticationProvider());
    auth.authenticationProvider(tokenAuthenticationProvider());

}

@Bean
public AuthenticationProvider tokenAuthenticationProvider() {
    return new SsoTokenAuthenticationProvider();
}

@Bean
public AuthenticationProvider daoAuthenticationProvider() {
    // DaoAuthenticationProvider requires a userDetailsService object to be attached.
    // So we build one. This replaces the AuthenticationConfiguration, which is commented out below

    // Build the userDetailsService
    User userThatMustMatch = new User("michael", "password", AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_USER,ROLE_RESTUSER"));
    Collection<UserDetails> users = new ArrayList<>();
    users.add(userThatMustMatch);
    InMemoryUserDetailsManager userDetailsService = new InMemoryUserDetailsManager(users);  

    // Create the DaoAuthenticationProvider that will handle all HTTP BASIC AUTH requests
    DaoAuthenticationProvider daoAuthProvider = new DaoAuthenticationProvider();
    daoAuthProvider.setUserDetailsService(userDetailsService);
    return daoAuthProvider;
}

SsoTokenAuthenticationFilter.java

public class SsoTokenAuthenticationFilter extends GenericFilterBean {

public final String HEADER_SECURITY_COOKIE = "LdapToken"; 

private AuthenticationManager authenticationManager;
private AuthenticationDetailsSource<HttpServletRequest,?> ssoTokenAuthenticationDetailsSource = new SsoTokenWebAuthenticationDetailsSource();

public SsoTokenAuthenticationFilter(AuthenticationManager authenticationManager) {
    this.authenticationManager = authenticationManager;
}

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    HttpServletRequest httpRequest = (HttpServletRequest) request;
    HttpServletResponse httpResponse = (HttpServletResponse) response;

    // check if SSO token is available. If not, pass down to next filter in chain
    try {
        Cookie[] cookies = httpRequest.getCookies();
        if (cookies == null){
            chain.doFilter(request, response);
            return;
        }
        Cookie ssoCookie = null;
        for (int i = 0; i < cookies.length; i++) {
            if (cookies[i].getName().equals("ssoToken"))
                ssoCookie = cookies[i];
            }
        if (ssoCookie == null){
            chain.doFilter(request, response);
            return;
        }

        // SSO token found, now authenticate and afterwards pass down to next filter in chain
        authenticateWithSsoToken(httpRequest);
        logger.debug("now the AuthenticationFilter passes down to next filter in chain");
        chain.doFilter(request, response);
    } catch (InternalAuthenticationServiceException internalAuthenticationServiceException) {
        SecurityContextHolder.clearContext();
        logger.error("Internal authentication service exception", internalAuthenticationServiceException);
        httpResponse.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
    } catch (AuthenticationException authenticationException) {
        SecurityContextHolder.clearContext();
        logger.debug("No or invalid SSO token");
        httpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED, authenticationException.getMessage());
    } 
}

private void authenticateWithSsoToken(HttpServletRequest request) throws IOException {
    System.out.println("+++ authenticateWithSSOToken +++");
    UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(null, null, AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_USER,ROLE_RESTUSER"));
    authRequest.setDetails(ssoTokenAuthenticationDetailsSource.buildDetails(request));        

    // Delegate authentication to SsoTokenAuthenticationProvider, he will call the SsoTokenAuthenticationProvider <-- because of the configuration in WebSecurityConfig.java
    Authentication authResult = authenticationManager.authenticate(authRequest);
}}

SsoTokenAuthenticationProvider.java

public class SsoTokenAuthenticationProvider implements AuthenticationProvider {

public SsoTokenAuthenticationProvider() {

}

@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
    SsoTokenWebAuthenticationDetails ssoTokenWebAuthenticationDetails = null;
    WebAuthenticationDetails webWebAuthenticationDetails = (WebAuthenticationDetails)authentication.getDetails();

    if (! (webWebAuthenticationDetails instanceof SsoTokenWebAuthenticationDetails)){
        // ++++++++++++++++++++++++
        // BASIC authentication....
        // ++++++++++++++++++++++++
        UsernamePasswordAuthenticationToken emptyToken = new UsernamePasswordAuthenticationToken(null, null);
        emptyToken.setDetails(null);
        return emptyToken; //return null works, too.
    }

    // ++++++++++++++++++++++++
    // LDAP authentication....
    // ++++++++++++++++++++++++
    ssoTokenWebAuthenticationDetails = (SsoTokenWebAuthenticationDetails)webWebAuthenticationDetails;       
    Cookie ssoTokenCookie = ssoTokenWebAuthenticationDetails.getSsoTokenCookie();

    // check if SSO cookie is available
    if (ssoTokenCookie == null){ 
        return new UsernamePasswordAuthenticationToken(null, null); //do basic auth.
    }
    String username = ssoTokenCookie.getValue();

    // Do your SSO token authentication here
    if (! username.equals("michael"))
        return new UsernamePasswordAuthenticationToken(null, null); //do basic auth.

    // Create new Authentication object. Name and password can be null (but you can set the values of course).
    // Be careful with your role names!
    // In WebSecurityConfig the role "USER" is automatically prefixed with String "ROLE_", so it is "ROLE_USER" in the end.
    UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(null, null, AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_USER,ROLE_RESTUSER"));
    authRequest.setDetails(ssoTokenWebAuthenticationDetails);

    // Don't let spring decide.. you already have made the right decisions. Tell spring you have an authenticated user.
    // vielleicht ist dieses obere Kommentar auch bullshit... ich lese das morgen noch mal nach...
    SecurityContextHolder.getContext().setAuthentication(authentication);
    return authentication;
}

@Override
public boolean supports(Class<?> authentication) {
    return authentication.equals(UsernamePasswordAuthenticationToken.class);
}
}

SsoTokenWebAuthenticationDetailsS​​ource.java

public class SsoTokenWebAuthenticationDetailsSource extends
    WebAuthenticationDetailsSource {

@Override
public WebAuthenticationDetails buildDetails(HttpServletRequest context) {
    return new SsoTokenWebAuthenticationDetails(context);
}

}

SsoTokenWebAuthenticationDetails.java

public class SsoTokenWebAuthenticationDetails extends WebAuthenticationDetails {
private static final long serialVersionUID = 1234567890L;

private Cookie ssoTokenCookie;

public SsoTokenWebAuthenticationDetails(HttpServletRequest request) {
    super(request);
    // Fetch cookie from request
    Cookie[] cookies = request.getCookies();

    Cookie ssoTokenCookie = null;
    for (int i = 0; i < cookies.length; i++) {
        if (cookies[i].getName().equals("SSOToken"))
            ssoTokenCookie= cookies[i];
        }
    this.setSsoTokenCookie(ssoTokenCookie);
}

public Cookie getSsoTokenCookie() {
    return ssoTokenCookie;
}

public void setSsoTokenCookie(Cookie ssoTokenCookie) {
    this.ssoTokenCookie = ssoTokenCookie;
}
}

我用一个视图的话来描述解决方案:

  1. Config 类保护任何/restapi具有角色的控制器ROLE_USER。可以使用 httpBasic 身份验证来完成身份验证,但在此之前您可以尝试基本身份验证。您必须尝试通过 ssoTokenCookie(如果可用)对用户进行身份验证。因此,您设置SsoTokenAuthenticationFilter作为基本身份验证之前的过滤器。被申请;被应用。
  2. Inside the filter, you check if a ssoTokenCookie is available in request.
    • 如果是,则将身份验证委托给标准 springAuthenticationManager. The AuthenticationManager知道你自己的SsoTokenAuthenticationProvider实现并将身份验证委托给它。在这里,拥有可用的 cookie 信息非常重要。这可以通过使用定制的WebAuthenticationDetails.
    • 如果不是,则将工作传递给链中的下一个过滤器。不奇怪,标准BasicAuthenticationFilter将被调用。因为你告诉 Spring 使用标准daoAuthenticationProvider in WebSecurityConfig.java,当在基本身份验证中输入正确的凭据时,Spring 可以对用户进行身份验证。对话
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

自定义 Spring Security 应用程序中的无限循环 的相关文章

随机推荐

  • 当我知道 CNAME 存在时,为什么 dns_get_record 不显示它们?

    我正在 PHP 中进行 DNS 记录查找 但遇到了一些令人困惑的事情 我查找了两个不同的域 每个域使用不同的主机和不同的权威名称服务器 我确信这两个域都有 CNAME 我使用这个在线工具查找了 DNS 记录 http network too
  • 使用实体框架自动编号

    我想循环遍历对象集合并将它们全部添加到表中 目标表有一个自动增量字段 如果我添加单个对象就没有问题 如果我添加两个主键都为零的对象 实体框架将失败 我可以手动指定主键 但尝试 EF 的全部目的是让生活更轻松 而不是更复杂 这是代码 收到的异
  • 检查更新查询是否成功[PHP,mysqli] [重复]

    这个问题在这里已经有答案了 我正在使用 PHP 和 mysqli 该程序正在做的是 如果在它设置密码的数据库中找到电子邮件添加和重置代码 它会要求重置代码和电子邮件地址 这部分功能正在工作 我需要这部分的帮助 我需要做的是告诉用户是否设置了
  • 是否可以强制 MapKit 显示所有注释而不进行聚类?

    我有两个类都符合MKAnnotation 我想知道有没有办法强制MapKit当用户缩小并显示所有注释时不聚集注释 上述解决方案对我不起作用 但是这个解决方案有效 final class CarPinMarkerView MKMarkerAn
  • Firefox 中图像顶部显示“提交查询”的图像按钮

    我的项目在 IE 和 Chrome 中都能正确显示 然而 在 FF 中 由于某种原因 图像按钮在其顶部显示 提交查询 我正在 CSS 中设置图像位置 它绝对是正确的 因为它在所有浏览器中都能正常工作 只是 FireFox 出于某种原因将 提
  • 使用 jquery 替换通配符文本

    我有一个包含公司信息 地址 电话等 的数据库 某些电话号码有国际代码 44 0 123 12345 其中 0 的数字因国家 地区而异 我需要去掉 0 我有以下代码 var el contactdetails el html el html
  • 错误:java.lang.NullPointerException:尝试调用虚拟方法“android.content.res.XmlResourceParser”

    我收到此错误 我是 android studio 的新手 我需要为 Unity 创建此插件以在运行时安装 apk 错误 尝试在空对象引用上调用虚拟方法 android content Context Android content Cont
  • 使用 XPath,如何根据节点的文本内容和属性值选择节点?

    给定这个 XML
  • 鼠标事件不会更新 winform 中的相机旋转

    我的应用程序有一个自定义面板 用于在 WinForm 中显示 XNA 屏幕 我目前已经展示了一个没有问题的测试模型 现在正在研究相机移动 我的相机是一个免费相机 不受任何特定目标的约束 但我一直无法让鼠标更新相机在其自身轴上的偏航和俯仰 我
  • Java 中的两个类之间如何使用接口进行通信?

    嗨 我一直在这里阅读一些类似的主题 但没有一个回答我的问题 有人说你甚至不能这样做 这不是一件好事 因为在这种情况下我无法完成我的课程 这是一些简单的代码 将每个块视为一个单独的类 public interface Interface vo
  • 在 R 中循环文件

    我正在使用 R 来计算文件中列的平均值 如下所示 R file1 read table x01 mean file1 V4 然而 我没有构建涉及 R 的循环的经验 仅使用 bash 我如何将其转换为一个循环 对文件夹中的每个文件执行此操作
  • file_get_contents() 是否使用缓存?

    如果我写 mypage file get contents www mywebsite com mypage htm 我第一次运行该脚本时 file get contents 肯定会向 www mywebsite com 发出 mypage
  • 学习 C++ 语言 [关闭]

    Closed 这个问题不符合堆栈溢出指南 目前不接受答案 我是一名 net c 程序员 但我也想学习 NET C 我是 c 的初学者 有没有从初学者到专家的网站 书籍或视频教程 不存在 Net c 这样的东西 也许你的意思是C CLI 这是
  • 混合模式 C++/CLI 性能注意事项 - 最佳实践

    我有一个 C CLI 库 它调用许多本机 C 方法 我读过许多线程 指出不应混合托管和非托管代码 我找不到任何说明如何避免这些开关以及为什么它会导致性能问题的信息 有人可以分享最佳实践吗 使用 C CLI 的唯一原因是它支持混合托管代码和本
  • 如何每次迭代增加一个字母 N 次并存储在数组中?

    letter array for i A i ZZ i letter i print r letter 从上面的脚本我做了一个循环A B C D ZZ 现在 我想把它变成A C E G I ZZ 2步骤而不是1 我需要指导才能做到这一点 这
  • 在 Firebase 中加入两个节点

    我正在开发一个应用程序 它应该显示来自两个节点 Firebase 的数据 Firebase DB 的结构如下 College 4F2EAB65 id 4F2EAB65 name SomeCollege A3C2ED31 id A3C2ED3
  • pandas:将DataFrame最后一行除以第一行

    这个问题类似于Python Pandas 按第一行划分 DataFrame 我有一个数据框 如下所示 1125400 5430095 1095751 2013 04 02 98 91 NaN 5626 79 2013 04 03 99 29
  • 从 Java 执行 EXE 并从 EXE 获取输入和输出

    我有一个EXE file addOne exe它不断地从控制台上的用户输入一个整数 不是命令行参数 并输出整数 1到控制台上 示例输出如下所示 1 2 6 7 29 30 我正在尝试编写一个java程序 它可以 Run the EXE 不断
  • Swift 2 错误处理问题

    我正在使用 REST 获取 JSON 数据 然后解析它 为此 我使用 NSJSONObjectWithData 据我所知 该方法过去在其参数内有一个错误处理程序 但它不再存在 在我的代码中 let err NSError let optio
  • 自定义 Spring Security 应用程序中的无限循环

    我们尝试用现有的 Spring Security Basic Login 替换开源应用程序中的 REST API 以实现使用令牌的自定义登录 我读过这篇关于该主题的博文 http javattitude com 2014 06 07 spr